<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"><title>对加密算法的学习 | Forgo7ten'blog</title><meta name="keywords" content="Android逆向"><meta name="author" content="Forgo7ten"><meta name="copyright" content="Forgo7ten"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="#ffffff"><meta name="description" content="[TOC] 序列密码(流密码) ¶  将明文消息按字符逐位进行加密。  RC4 ¶  RC4(Rivest Cipher 4)是一种流加密算法，密钥长度可变。在给定一密钥时，会生成一固定序列的字节流，用于和明文进行异或。 用途：WEP、WPA、SSL、TLS 原理 ¶  RSA主要包括初始化算法(KSA)和伪随机子密码生成算法(PRGA)，其核心部分的S-box长度可为任意，但一般为256字节。">
<meta property="og:type" content="article">
<meta property="og:title" content="对加密算法的学习">
<meta property="og:url" content="https://forgo7ten.github.io/AndroidReverse/2022/Learning_about_cryptographic_algorithms/index.html">
<meta property="og:site_name" content="Forgo7ten&#39;blog">
<meta property="og:description" content="[TOC] 序列密码(流密码) ¶  将明文消息按字符逐位进行加密。  RC4 ¶  RC4(Rivest Cipher 4)是一种流加密算法，密钥长度可变。在给定一密钥时，会生成一固定序列的字节流，用于和明文进行异或。 用途：WEP、WPA、SSL、TLS 原理 ¶  RSA主要包括初始化算法(KSA)和伪随机子密码生成算法(PRGA)，其核心部分的S-box长度可为任意，但一般为256字节。">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="http://forgo7ten.gitee.io/store/imgs/18.jpg">
<meta property="article:published_time" content="2022-02-06T16:00:00.000Z">
<meta property="article:modified_time" content="2022-02-06T16:00:00.000Z">
<meta property="article:author" content="Forgo7ten">
<meta property="article:tag" content="Android逆向">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="http://forgo7ten.gitee.io/store/imgs/18.jpg"><link rel="shortcut icon" href="/images/favicon.jpg"><link rel="canonical" href="https://forgo7ten.github.io/AndroidReverse/2022/Learning_about_cryptographic_algorithms/"><link rel="preconnect" href="//cdn.jsdelivr.net"/><link rel="preconnect" href="//hm.baidu.com"/><link rel="preconnect" href="//www.clarity.ms"/><link rel="preconnect" href="//fonts.googleapis.com" crossorigin=""/><link rel="preconnect" href="//busuanzi.ibruce.info"/><meta name="google-site-verification" content="8L0ZjthONyq6-m7FniRTH8A7Bh0x-KOPZbKOcNimnYA"/><meta name="baidu-site-verification" content="code-gjVsyPt7yr"/><link rel="stylesheet" href="/css/index.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6/css/all.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/node-snackbar/dist/snackbar.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox.css" media="print" onload="this.media='all'"><script>var _hmt = _hmt || [];
(function() {
  var hm = document.createElement("script");
  hm.src = "https://hm.baidu.com/hm.js?b076845d73a4f28b3c7401b2a0a8a9db";
  var s = document.getElementsByTagName("script")[0]; 
  s.parentNode.insertBefore(hm, s);
})();
</script><script>(function(c,l,a,r,i,t,y){
    c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)};
    t=l.createElement(r);t.async=1;t.src="https://www.clarity.ms/tag/"+i;
    y=l.getElementsByTagName(r)[0];y.parentNode.insertBefore(t,y);
})(window, document, "clarity", "script", "9zbibmmffi");</script><link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Titillium+Web&amp;display=swap" media="print" onload="this.media='all'"><script>const GLOBAL_CONFIG = { 
  root: '/',
  algolia: undefined,
  localSearch: {"path":"search.xml","languages":{"hits_empty":"找不到您查询的内容：${query}"}},
  translate: {"defaultEncoding":2,"translateDelay":0,"msgToTraditionalChinese":"繁","msgToSimplifiedChinese":"簡"},
  noticeOutdate: undefined,
  highlight: {"plugin":"highlighjs","highlightCopy":true,"highlightLang":true,"highlightHeightLimit":300},
  copy: {
    success: '复制成功',
    error: '复制错误',
    noSupport: '浏览器不支持'
  },
  relativeDate: {
    homepage: true,
    post: false
  },
  runtime: '天',
  date_suffix: {
    just: '刚刚',
    min: '分钟前',
    hour: '小时前',
    day: '天前',
    month: '个月前'
  },
  copyright: undefined,
  lightbox: 'fancybox',
  Snackbar: {"chs_to_cht":"你已切换为繁体","cht_to_chs":"你已切换为简体","day_to_night":"你已切换为深色模式","night_to_day":"你已切换为浅色模式","bgLight":"#49b1f5","bgDark":"#121212","position":"bottom-left"},
  source: {
    justifiedGallery: {
      js: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery@2/dist/fjGallery.min.js',
      css: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery@2/dist/fjGallery.min.css'
    }
  },
  isPhotoFigcaption: false,
  islazyload: true,
  isAnchor: true
}</script><script id="config-diff">var GLOBAL_CONFIG_SITE = {
  title: '对加密算法的学习',
  isPost: true,
  isHome: false,
  isHighlightShrink: false,
  isToc: true,
  postUpdate: '2022-02-07 00:00:00'
}</script><noscript><style type="text/css">
  #nav {
    opacity: 1
  }
  .justified-gallery img {
    opacity: 1
  }

  #recent-posts time,
  #post-meta time {
    display: inline !important
  }
</style></noscript><script>(win=>{
    win.saveToLocal = {
      set: function setWithExpiry(key, value, ttl) {
        if (ttl === 0) return
        const now = new Date()
        const expiryDay = ttl * 86400000
        const item = {
          value: value,
          expiry: now.getTime() + expiryDay,
        }
        localStorage.setItem(key, JSON.stringify(item))
      },

      get: function getWithExpiry(key) {
        const itemStr = localStorage.getItem(key)

        if (!itemStr) {
          return undefined
        }
        const item = JSON.parse(itemStr)
        const now = new Date()

        if (now.getTime() > item.expiry) {
          localStorage.removeItem(key)
          return undefined
        }
        return item.value
      }
    }
  
    win.getScript = url => new Promise((resolve, reject) => {
      const script = document.createElement('script')
      script.src = url
      script.async = true
      script.onerror = reject
      script.onload = script.onreadystatechange = function() {
        const loadState = this.readyState
        if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
        script.onload = script.onreadystatechange = null
        resolve()
      }
      document.head.appendChild(script)
    })
  
      win.activateDarkMode = function () {
        document.documentElement.setAttribute('data-theme', 'dark')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
        }
      }
      win.activateLightMode = function () {
        document.documentElement.setAttribute('data-theme', 'light')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#ffffff')
        }
      }
      const t = saveToLocal.get('theme')
    
          if (t === 'dark') activateDarkMode()
          else if (t === 'light') activateLightMode()
        
      const asideStatus = saveToLocal.get('aside-status')
      if (asideStatus !== undefined) {
        if (asideStatus === 'hide') {
          document.documentElement.classList.add('hide-aside')
        } else {
          document.documentElement.classList.remove('hide-aside')
        }
      }
    
    const detectApple = () => {
      if(/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)){
        document.documentElement.classList.add('apple')
      }
    }
    detectApple()
    })(window)</script><meta name="generator" content="Hexo 5.4.0"><link rel="alternate" href="/atom.xml" title="Forgo7ten'blog" type="application/atom+xml">
</head><body><div id="loading-box"><div class="loading-left-bg"></div><div class="loading-right-bg"></div><div class="spinner-box"><div class="configure-border-1"><div class="configure-core"></div></div><div class="configure-border-2"><div class="configure-core"></div></div><div class="loading-word">加载中...</div></div></div><div id="web_bg"></div><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img is-center"><img src="/images/avatar.jpg" onerror="onerror=null;src='/img/friend_404.gif'" alt="avatar"/></div><div class="site-data is-center"><div class="data-item"><a href="/archives/"><div class="headline">文章</div><div class="length-num">20</div></a></div><div class="data-item"><a href="/tags/"><div class="headline">标签</div><div class="length-num">8</div></a></div><div class="data-item"><a href="/categories/"><div class="headline">分类</div><div class="length-num">6</div></a></div></div><hr/><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><i class="fa-fw fas fa-compass"></i><span> 目录</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> 归档</span></a></li><li><a class="site-page child" href="/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></li><li><a class="site-page child" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></li></ul></div><div class="menus_item"><a class="site-page" href="/atom.xml"><i class="fa-fw fa fa-rss"></i><span> RSS订阅</span></a></div><div class="menus_item"><a class="site-page" href="/link/"><i class="fa-fw fas fa-link"></i><span> 友链</span></a></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div><div class="menus_item"><a class="site-page" href="/messageboard/"><i class="fa-fw fas fa-comment-dots"></i><span> 留言板</span></a></div></div></div></div><div class="post" id="body-wrap"><header class="post-bg" id="page-header" style="background-image: url('http://forgo7ten.gitee.io/store/imgs/18.jpg')"><nav id="nav"><span id="blog_name"><a id="site-name" href="/">Forgo7ten'blog</a></span><div id="menus"><div id="search-button"><a class="site-page social-icon search"><i class="fas fa-search fa-fw"></i><span> 搜索</span></a></div><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><i class="fa-fw fas fa-compass"></i><span> 目录</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> 归档</span></a></li><li><a class="site-page child" href="/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></li><li><a class="site-page child" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></li></ul></div><div class="menus_item"><a class="site-page" href="/atom.xml"><i class="fa-fw fa fa-rss"></i><span> RSS订阅</span></a></div><div class="menus_item"><a class="site-page" href="/link/"><i class="fa-fw fas fa-link"></i><span> 友链</span></a></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div><div class="menus_item"><a class="site-page" href="/messageboard/"><i class="fa-fw fas fa-comment-dots"></i><span> 留言板</span></a></div></div><div id="toggle-menu"><a class="site-page"><i class="fas fa-bars fa-fw"></i></a></div></div></nav><div id="post-info"><h1 class="post-title">对加密算法的学习</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">发表于</span><time class="post-meta-date-created" datetime="2022-02-06T16:00:00.000Z" title="发表于 2022-02-07 00:00:00">2022-02-07</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2022-02-06T16:00:00.000Z" title="更新于 2022-02-07 00:00:00">2022-02-07</time></span><span class="post-meta-categories"><span class="post-meta-separator">|</span><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/categories/Android%E9%80%86%E5%90%91/">Android逆向</a></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-wordcount"><i class="far fa-file-word fa-fw post-meta-icon"></i><span class="post-meta-label">字数总计:</span><span class="word-count">11k</span><span class="post-meta-separator">|</span><i class="far fa-clock fa-fw post-meta-icon"></i><span class="post-meta-label">阅读时长:</span><span>45分钟</span></span><span class="post-meta-separator">|</span><span class="post-meta-pv-cv" id="" data-flag-title="对加密算法的学习"><i class="far fa-eye fa-fw post-meta-icon"></i><span class="post-meta-label">阅读量:</span><span id="busuanzi_value_page_pv"></span></span></div></div></div></header><main class="layout" id="content-inner"><div id="post"><article class="post-content" id="article-container"><p>[TOC]</p>
<h1 id="序列密码-流密码">序列密码(流密码)<a class="header-anchor" href="#序列密码-流密码"> ¶ </a></h1>
<p>将明文消息按字符逐位进行加密。</p>
<p><img src= "" data-lazy-src="/AndroidReverse/2022/Learning_about_cryptographic_algorithms/stream_cipher.png" alt="stream_cipher"></p>
<h2 id="RC4">RC4<a class="header-anchor" href="#RC4"> ¶ </a></h2>
<p>RC4(Rivest Cipher 4)是一种流加密算法，密钥长度可变。在给定一密钥时，会生成一固定序列的字节流，用于和明文进行异或。</p>
<p>用途：WEP、WPA、SSL、TLS</p>
<h3 id="原理">原理<a class="header-anchor" href="#原理"> ¶ </a></h3>
<p>RSA主要包括初始化算法(KSA)和伪随机子密码生成算法(PRGA)，其核心部分的S-box长度可为任意，但一般为256字节。</p>
<p>RC4算法的关键是根据明文和密钥生成相应的密钥流，密钥流长度和明文长度相等，<code>密文[i] = 明文[i] ^ 密钥流[i]</code></p>
<h4 id="初始化算法-KSA">初始化算法(KSA)<a class="header-anchor" href="#初始化算法-KSA"> ¶ </a></h4>
<ol>
<li>
<p>初始化存储0-255字节的S-box和T-box</p>
<p>填充key到256个字节数组中称为T-box，（key不满256则循环填充、超过则只取前256）</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">N = <span class="number">256</span>;</span><br><span class="line"><span class="keyword">for</span> (i=<span class="number">0</span>;i &lt; N;i++) &#123;</span><br><span class="line">    S[i] = i;</span><br><span class="line">    T[i] = key[i % key_len];</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><img src= "" data-lazy-src="/AndroidReverse/2022/Learning_about_cryptographic_algorithms/rc4_s_t.png" alt="img"></p>
</li>
<li>
<p>初始置换状态向量S-box</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">N = <span class="number">256</span>;</span><br><span class="line"><span class="keyword">for</span> (i=<span class="number">0</span>, j=<span class="number">0</span>; i&lt; N; i++)</span><br><span class="line">&#123;</span><br><span class="line">	j=(j+S[i]+T[i])% N;</span><br><span class="line">    <span class="comment">// 对两数进行交换</span></span><br><span class="line">	swap(S[i], S[j]);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><img src= "" data-lazy-src="/AndroidReverse/2022/Learning_about_cryptographic_algorithms/rc4_s.png" alt="img"></p>
</li>
</ol>
<h4 id="伪随机子密码生成算法-PRGA">伪随机子密码生成算法(PRGA)<a class="header-anchor" href="#伪随机子密码生成算法-PRGA"> ¶ </a></h4>
<p>产生密钥流，并与明文异或得到密文</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">i=<span class="number">0</span>;</span><br><span class="line">j=<span class="number">0</span>;</span><br><span class="line"><span class="keyword">for</span> (k = <span class="number">0</span>; k &lt; data_len; k++) &#123;</span><br><span class="line">    i = (i + <span class="number">1</span>) % <span class="number">256</span>;</span><br><span class="line">    j = (j + S[i]) % <span class="number">256</span>;</span><br><span class="line">    </span><br><span class="line">    tmp = S[i];</span><br><span class="line">    S[i] = S[j]; <span class="comment">//交换S[x]和S[y]</span></span><br><span class="line">    S[j] = tmp;</span><br><span class="line">    </span><br><span class="line">    t = (S[i] + S[j]) % <span class="number">256</span>;</span><br><span class="line">    ckey = S[t];	<span class="comment">// ckey为生成的密钥流</span></span><br><span class="line">    data[k] ^= ckey;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><img src= "" data-lazy-src="/AndroidReverse/2022/Learning_about_cryptographic_algorithms/rc4_key.png" alt="img"></p>
<h3 id="实现">实现<a class="header-anchor" href="#实现"> ¶ </a></h3>
<h4 id="C语言">C语言<a class="header-anchor" href="#C语言"> ¶ </a></h4>
<script src="https://gist.github.com/Forgo7ten/28a2c20ade914e962a8c5714d36ccbca.js"></script>
<h1 id="分组密码-块加密">分组密码(块加密)<a class="header-anchor" href="#分组密码-块加密"> ¶ </a></h1>
<p>将明文消息分组(每组多个字符)，逐组进行加密。</p>
<h2 id="分组密码概念">分组密码概念<a class="header-anchor" href="#分组密码概念"> ¶ </a></h2>
<ul>
<li>padding，即 padding(填补) 到指定分组长度。</li>
<li>分组加密工作模式，即明文分组加密的方式。</li>
</ul>
<p>分组密码最后不足一个区块的大小，称为短块，短块的处理方法有填充法、流密码加密法、密文挪用技术。</p>
<h3 id="分组密码五种工作模式">分组密码五种工作模式<a class="header-anchor" href="#分组密码五种工作模式"> ¶ </a></h3>
<p>DES算法工作模式被标准化，根据数据加密时每个加密区块间的关联方式来区分，可以分为以下4种：</p>
<ul>
<li>电子密码本模式(Electronic Code Book, ECB)</li>
<li>密文链接模式(Cipher Book Chaining, CBC)</li>
<li>密文反馈模式(Cipher Feed Back, CFB)</li>
<li>输出反馈模式(Output Feed Back, OFB)</li>
<li>（AES标准额外添加一种）计数器模式(Counter, CTR)</li>
</ul>
<p>这些工作模式可适用于各种分组密码算法</p>
<table>
<thead>
<tr>
<th style="text-align:center">模式</th>
<th style="text-align:center">描述</th>
<th style="text-align:center">使用途径</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:center">ECB（电码本模式）</td>
<td style="text-align:center">用于每一个明文组<strong>独立</strong>的用同一密钥加密</td>
<td style="text-align:center">传送短数据 ( 如一个加密密钥）</td>
</tr>
<tr>
<td style="text-align:center">CBC（密码分组链接模式）</td>
<td style="text-align:center">加密算法的输入是当前明文组与前一密文组的异或</td>
<td style="text-align:center">传送数据分组；认证</td>
</tr>
<tr>
<td style="text-align:center">CFB（密码反馈模式）</td>
<td style="text-align:center">每次只处理输入的 j 比特 , 将上一次的密文用作加密算法的输入以产生伪随机输出 , 该输出再与当前明文异或以产生当前密文</td>
<td style="text-align:center">传送数据分组；认证</td>
</tr>
<tr>
<td style="text-align:center">OFB（输出反馈模式）</td>
<td style="text-align:center">与 CFB 类似 ,不同之处是本次加密算法的输入为前一次加密算法的输出</td>
<td style="text-align:center">有扰信道传送数据</td>
</tr>
<tr>
<td style="text-align:center">CTR (计数器模式)</td>
<td style="text-align:center">与CFB、OFB些许类似，但不同之处是定义一个计数器来加密后进行异或</td>
<td style="text-align:center"></td>
</tr>
</tbody>
</table>
<h4 id="电子密码本模式-ECB">电子密码本模式(ECB)<a class="header-anchor" href="#电子密码本模式-ECB"> ¶ </a></h4>
<p><img src= "" data-lazy-src="/AndroidReverse/2022/Learning_about_cryptographic_algorithms/ECB.png" alt="ECB图解"></p>
<p>ECB是最简单的运行模式，它一次对一个64bit的明文分组利用相同的密钥进行加密，当密钥取定时，对明文的每一个分组，都有一个惟一的密文与之对应。如果消息长于64比特,则将其分为长为64比特的分组，最后一个分组如果不够64bit，则需要对这个分组进行填充。解密过程也是一次对一个分组解密，而且每次解密都使用同一密钥。</p>
<p>每次加密均产生独立的密文分组，每组的加密结果不会对其他分组差生影响，相同的明文加密后对应产生相同的密文，无初始化向量(加密向量,iv)</p>
<ul>
<li>优点：简单易行，便于实现并行操作，没有误差传递的问题</li>
<li>缺点：不能隐藏明文的模式，如果同一明文重复出现、密文也会重复，密文内容很容易被替换、重排、删除、重放；对明文进行主动攻击的可能性较高</li>
<li>用途：适合加密密钥，随机数等短数据。</li>
</ul>
<h4 id="密文链接模式-CBC">密文链接模式(CBC)<a class="header-anchor" href="#密文链接模式-CBC"> ¶ </a></h4>
<p>⊕表示异或</p>
<p><img src= "" data-lazy-src="/AndroidReverse/2022/Learning_about_cryptographic_algorithms/CBC.png" alt="CBC图解"></p>
<p>为了解决ECB模式的密文块相同的缺点，CBC的模式引入了一个初始向量概念(IV)。在第一次加密前，会使用初始化向量与第一个明文分组异或，生成的数据分组再进行加密；加密第二个分组之前，会拿第一块的密文数据与第二个明文分组进行异或运算后再进行加密，以此类推，解密时也是在解密后，再与前一分组进行异或运算，生成最终的明文。</p>
<ul>
<li>优点：CBC加密后密文上下文关联，即使明文出现重复信息也不会产生相同密文；密文内容如果被替换重排删除重放或传输错误，后续密文即被破坏，无法完成解密还原。</li>
<li>缺点：不利于并行计算；误差传递；需要初始化向量(IV)</li>
<li>用途：可加密任意长度的数据，适用于计算产生检测数据完整性的消息认证码MAC</li>
</ul>
<h4 id="密码反馈模式-CFB">密码反馈模式(CFB)<a class="header-anchor" href="#密码反馈模式-CFB"> ¶ </a></h4>
<p>利用CFB或者OFB模式，可将DES转换为流密码。它可以按字节逐个进行加密解密，也可以按照n位字节处理。</p>
<p>设传送的每个<strong>单元</strong>(如一个字符)<strong>长度</strong>是<strong>j比特</strong>(通常取8bit)，与CBC一样，明文单元被链接到一起，使得密文是前面所有明文的函数</p>
<p><img src= "" data-lazy-src="/AndroidReverse/2022/Learning_about_cryptographic_algorithms/CFB.png" alt="CFB图解"></p>
<p>加密时，加密算法的输入是64比特移位寄存器，初值为某个初始向量IV。加密算法输出的最左(最高有效位) j 比特与明文的第一个单元P<sub>1</sub>异或，产生出的密文的第一个单元C<sub>1</sub>，并传送该单元。然后将移位寄存器的内容左移 j 位，并将C<sub>1</sub>送入送入移位寄存器最右边(最低有效位) j 位。这一过程继续到明文所有单元都被加密为止。</p>
<blockquote>
<p>通俗解释，看图，首先j比特为加密的单元长度，初次的移位寄存器为IV，先将其进行DES加密，之后选取左侧的j比特与明文的第一个单元P<sub>1</sub>进行异或，之后将原先的IV左移j位(抛弃运算完成的j位)，然后将P<sub>1</sub>异或结果C<sub>1</sub>( j 比特) 填补到移位寄存器的右侧(最低有效位) j 位，并开始下一次的加密、异或。</p>
</blockquote>
<p>解密时，将受到的密文单元与加密函数的输出进行异或。</p>
<ul>
<li>优点：隐藏了明文的模式，每个分组加密结果必受前面所有分组内容的影响，多次相同明文均产生不同密文；分组密码转化为流模式，可产生密钥流；可及时加密传送小于分组的数据。</li>
<li>缺点：不利于并行计算；存在误差传送；需要初始化向量。</li>
<li>用途：因错误传播无界，可用于检查发现明文密文的篡改。</li>
</ul>
<h4 id="输出反馈模式-OFB">输出反馈模式(OFB)<a class="header-anchor" href="#输出反馈模式-OFB"> ¶ </a></h4>
<p>OFB模式的结构类似于CFB，不同之处在于：OFB是将加密算法的输出反馈到移位寄存器，而CFB则是将密文单元反馈到移位寄存器。</p>
<p><img src= "" data-lazy-src="/AndroidReverse/2022/Learning_about_cryptographic_algorithms/OFB.png" alt="OFB图解"></p>
<ul>
<li>优点：传输过程中的比特错误不会被传播、后各明文单元不受影响（无误差传送问题）；</li>
<li>缺点：不利于并行运算，比CFB模式更易受到对消息流的篡改攻击。</li>
<li>用途：适用于加密冗余性较大的数据，如语音和图像数据。</li>
</ul>
<h4 id="计数器模式-CTR">计数器模式(CTR)<a class="header-anchor" href="#计数器模式-CTR"> ¶ </a></h4>
<p>CTR模式（Counter mode，CM）也被称为ICM模式（Integer Counter Mode，整数计数模式）和SIC模式（Segmented Integer Counter），与OFB相似，CTR将块密码变为流密码。它通过递增一个加密计数器以产生连续的密钥流，其中，计数器可以是任意保证长时间不产生重复输出的函数，但使用一个普通的计数器是最简单和最常见的做法。</p>
<p>加密：通过对逐次累加的计数器<strong>加密</strong>来生成密钥分组，与明文分组异或产生密文分组。</p>
<p>解密：同加密。</p>
<p><img src= "" data-lazy-src="/AndroidReverse/2022/Learning_about_cryptographic_algorithms/CTR.png" alt="CTR图解"></p>
<p>**例如：**AES-128，首先选择一个IV（长度小于分组长度，比如96位），而剩下的32位则由计数器使用，并且该CTR值初始化为0。在会话期间加密的每个分组，计数器都会递增而IV则保持不变。</p>
<ul>
<li>优点：可并行计算</li>
</ul>
<h4 id="明文密码块链接-PCBC">明文密码块链接(PCBC)<a class="header-anchor" href="#明文密码块链接-PCBC"> ¶ </a></h4>
<p>PCBC 的全称为明文密码块链接（Plaintext cipher-block chaining）。也称为填充密码块链接（Propagating cipher-block chaining）。</p>
<p><strong>加密</strong></p>
<p><img src= "" data-lazy-src="/AndroidReverse/2022/Learning_about_cryptographic_algorithms/pcbc_encryption.png" alt="pcbc_encryption"></p>
<p><strong>解密</strong></p>
<p><img src= "" data-lazy-src="/AndroidReverse/2022/Learning_about_cryptographic_algorithms/pcbc_decryption.png" alt="pcbc_decryption"></p>
<h3 id="分组密码填充模式">分组密码填充模式<a class="header-anchor" href="#分组密码填充模式"> ¶ </a></h3>
<p><strong>需要注意的是，即使消息的长度是块大小的整数倍，仍然需要填充。</strong>（其它 <a target="_blank" rel="noopener" href="https://www.di-mgt.com.au/cryptopad.html">填充规则</a>）</p>
<h4 id="NoPadding">NoPadding<a class="header-anchor" href="#NoPadding"> ¶ </a></h4>
<p>不填充，在此填充下原始数据<strong>必须</strong>是分组大小的整数倍，非整数倍时无法使用该模式</p>
<h4 id="PKCS5Padding-PKCS7Padding">PKCS5Padding / PKCS7Padding<a class="header-anchor" href="#PKCS5Padding-PKCS7Padding"> ¶ </a></h4>
<p>填充至符合块大小的整数倍，填充值为[<strong>填充数量数</strong>]</p>
<ul>
<li>
<p>原始：<code>FF FF FF FF FF FF FF FF FF</code> (9 byte)</p>
</li>
<li>
<p>填充：<code>FF FF FF FF FF FF FF FF FF 07 07 07 07 07 07 07</code> (假设填充至16byte，需7byte，则填充值为<code>07</code>)</p>
</li>
</ul>
<p>特殊情况：PKCS#7规定Padding必须存在，因此即使原始数据是16的整数倍，也需要在末尾追加16字节的Padding，即正好追加一个块，这个块每个字节都是<code>0x10</code></p>
<p><code>PKCS5Padding</code> 的分组大小固定为 8 个字节，而 <code>PKCS7Padding</code> 的分组大小可以在 1~255 字节。但 SunJCE 的 Provider 实现中 <code>PKCS5Padding</code> 也按 <code>PKCS7Padding</code> 来进行处理了（因为<strong>AES并没有64位的块, 如果采用PKCS5, 那么实质上就是采用PKCS7</strong>）。</p>
<h4 id="ANSI-X923Padding">ANSI X923Padding<a class="header-anchor" href="#ANSI-X923Padding"> ¶ </a></h4>
<p>填充至符合块大小的整数倍，填充值<strong>最后一个字节</strong>为[<strong>填充数量数</strong>]，其他字节填 <code>00</code></p>
<ul>
<li>原始：<code>FF FF FF FF FF FF FF FF FF</code></li>
<li>填充：<code>FF FF FF FF FF FF FF FF FF 00 00 00 00 00 00 07</code></li>
</ul>
<p>特殊情况：只有一个字节填充，则直接填充<code>01</code>(填充数量)</p>
<h4 id="ISO10126Padding">ISO10126Padding<a class="header-anchor" href="#ISO10126Padding"> ¶ </a></h4>
<p>填充至符合块大小的整数倍，填充值<strong>最后一个字节</strong>为[<strong>填充数量数</strong>]，其他字节随机处理</p>
<ul>
<li>原始：<code>FF FF FF FF FF FF FF FF FF</code></li>
<li>填充：<code>FF FF FF FF FF FF FF FF FF 3F 7A B4 09 14 36 07</code> (填充7byte，最后填充值为<code>07</code>，其余填充随机)</li>
</ul>
<p>特殊情况：只有一个字节填充，则直接填充<code>01</code>(填充数量)</p>
<h4 id="ISO7816-4Padding">ISO7816-4Padding<a class="header-anchor" href="#ISO7816-4Padding"> ¶ </a></h4>
<p>填充至符合块大小的整数倍，填充值第一个字节为 <code>0x80</code>，其他字节填 <code>00</code></p>
<ul>
<li>原始：<code>FF FF FF FF FF FF FF FF FF</code></li>
<li>填充：<code>FF FF FF FF FF FF FF FF FF 80 00 00 00 00 00 00</code></li>
</ul>
<h4 id="ZeroBytePadding">ZeroBytePadding<a class="header-anchor" href="#ZeroBytePadding"> ¶ </a></h4>
<p>填充至符合块大小的整数倍，填充值为 0</p>
<ul>
<li>原始：<code>FF FF FF FF FF FF FF FF FF</code></li>
<li>填充：<code>FF FF FF FF FF FF FF FF FF 00 00 00 00 00 00 00</code></li>
</ul>
<h4 id="TBCPadding（Trailing-Bit-Compliment）">TBCPadding（Trailing-Bit-Compliment）<a class="header-anchor" href="#TBCPadding（Trailing-Bit-Compliment）"> ¶ </a></h4>
<p>填充至符合块大小的整数倍，原文最后一个bit位为<code>1</code>时填充 <code>00</code>，最后一位为<code>0</code>时填充<code>FF</code></p>
<ul>
<li>原始：<code>FF FF FF FF FF FF FF FF FF</code></li>
<li>填充：<code>FF FF FF FF FF FF FF FF FF 00 00 00 00 00 00 00</code></li>
<li>原始：<code>FF FF FF FF FF FF FF FF F0</code></li>
<li>填充：<code>FF FF FF FF FF FF FF FF F0 FF FF FF FF FF FF FF</code></li>
</ul>
<h4 id="PKCS1Padding">PKCS1Padding<a class="header-anchor" href="#PKCS1Padding"> ¶ </a></h4>
<p>该填充模式是 <strong>RSA 加密中使用</strong>的，详见 <a target="_blank" rel="noopener" href="https://datatracker.ietf.org/doc/html/rfc2313">RFC 2313 - PKCS #1: RSA Encryption Version 1.5 (ietf.org)</a>。</p>
<p>要求：必须比RSA钥模长(modulus)短至少11byte，也就是<code>RSA_size(rsa) - 11</code>，输出和modulus一样长</p>
<p>例如：密钥长度为1024位(bit)，则输出的密文块长度为128byte，输入的明文块长度则为<code>128-11 = 117byte</code>；如果明文过长、需要切割；明文较短、需要填充，填充规则如下</p>
<p>RSA 加密时，需要将原文填充至密钥大小，加密块是一个8位字节串<code>EB</code>，它由块标记<code>BT</code> 、填充块<code>PS</code>、原数据<code>D</code>组成：<code>EB = 00 | BT | PS | 00 | D</code></p>
<ul>
<li><code>00</code> 为固定字节</li>
<li><code>BT</code> 为处理模式。私钥操作为 <code>00</code> 或 <code>01</code>，公钥操作时为 <code>02</code></li>
<li><code>PS</code> 为填充字节块，填充数量为 <code>k - 3 - D</code>(减去的3即为<code>00|BT|00</code>)，<code>k</code> 表示密钥长度，<code>D</code> 表示原文长度。<code>PS</code> 的最小长度为 <code>8</code> 个字节。填充的值根据 <code>BT</code> 值不同而不同：
<ul>
<li><code>BT = 00</code> 时，填充全 <code>00</code></li>
<li><code>BT = 01</code> 时，填充全 <code>FF</code></li>
<li><code>BT = 02</code> 时，随机填充，但不能为 <code>00</code></li>
</ul>
</li>
<li><code>D</code> 为填充前原文</li>
</ul>
<h2 id="DES">DES<a class="header-anchor" href="#DES"> ¶ </a></h2>
<ul>
<li>分组加密算法：以64位为分组。64位明文输入，64位密文输出</li>
<li>对称算法：加密和解密使用同一秘钥。</li>
<li>密钥 64 位，使用 64 位密钥中的 56 位，剩余的 8 位要么丢弃，要么作为奇偶校验位(第8、16、24、32、40、48、56、64作为校验位)。</li>
<li>Feistel 迭代结构
<ul>
<li>明文经过 16 轮迭代得到密文。</li>
<li>密文经过类似的 16 轮迭代得到明文。</li>
</ul>
</li>
</ul>
<h3 id="原理-2">原理<a class="header-anchor" href="#原理-2"> ¶ </a></h3>
<p>大致图</p>
<p><img src= "" data-lazy-src="/AndroidReverse/2022/Learning_about_cryptographic_algorithms/DES-0.png" alt="DES-0"></p>
<p>F函数</p>
<p><img src= "" data-lazy-src="/AndroidReverse/2022/Learning_about_cryptographic_algorithms/DES-1.png" alt="DES-1"></p>
<p>密钥生成图</p>
<p><img src= "" data-lazy-src="/AndroidReverse/2022/Learning_about_cryptographic_algorithms/DES-2.png" alt="DES-2"></p>
<h3 id="实现-2">实现<a class="header-anchor" href="#实现-2"> ¶ </a></h3>
<h4 id="Java">Java<a class="header-anchor" href="#Java"> ¶ </a></h4>
<script src="https://gist.github.com/Forgo7ten/e04b2095d197200bc6b535597008510d.js"></script>
<h2 id="DESede-3DES">DESede(3DES)<a class="header-anchor" href="#DESede-3DES"> ¶ </a></h2>
<p>DESede同时又可称为3DES(三重DES)或TripleDES</p>
<p>三重 DES 的加解密方式如下</p>
<p><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>C</mi><mo>=</mo><msub><mi>E</mi><mrow><mi>k</mi><mn>3</mn></mrow></msub><mo stretchy="false">(</mo><msub><mi>D</mi><mrow><mi>k</mi><mn>2</mn></mrow></msub><mo stretchy="false">(</mo><msub><mi>E</mi><mrow><mi>k</mi><mn>1</mn></mrow></msub><mo stretchy="false">(</mo><mi>P</mi><mo stretchy="false">)</mo><mo stretchy="false">)</mo><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">C=E_{k3}(D_{k2}(E_{k1}(P)))</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.07153em;">C</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.05764em;">E</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361em;"><span style="top:-2.55em;margin-left:-0.0576em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span><span class="mord mtight">3</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361em;"><span style="top:-2.55em;margin-left:-0.0278em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span><span class="mord mtight">2</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.05764em;">E</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361em;"><span style="top:-2.55em;margin-left:-0.0576em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mclose">)))</span></span></span></span></p>
<p><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>P</mi><mo>=</mo><msub><mi>D</mi><mrow><mi>k</mi><mn>1</mn></mrow></msub><mo stretchy="false">(</mo><msub><mi>E</mi><mrow><mi>k</mi><mn>2</mn></mrow></msub><mo stretchy="false">(</mo><msub><mi>D</mi><mrow><mi>k</mi><mn>3</mn></mrow></msub><mo stretchy="false">(</mo><mi>C</mi><mo stretchy="false">)</mo><mo stretchy="false">)</mo><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">P=D_{k1}(E_{k2}(D_{k3}(C)))</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361em;"><span style="top:-2.55em;margin-left:-0.0278em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.05764em;">E</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361em;"><span style="top:-2.55em;margin-left:-0.0576em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span><span class="mord mtight">2</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361em;"><span style="top:-2.55em;margin-left:-0.0278em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span><span class="mord mtight">3</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07153em;">C</span><span class="mclose">)))</span></span></span></span></p>
<p>在选择密钥时，可以有两种方法</p>
<ul>
<li>3 个不同的密钥，k1，k2，k3 互相独立，一共 168 比特。</li>
<li>2 个不同的密钥，k1 与 k2 独立，k3=k1，112 比特。</li>
</ul>
<p>当三个密钥均相同时，此时与DES加密无异</p>
<h3 id="实现-3">实现<a class="header-anchor" href="#实现-3"> ¶ </a></h3>
<h3 id="Java-2">Java<a class="header-anchor" href="#Java-2"> ¶ </a></h3>
<p>在Java中，传入的key字节数组需满足<code>length==18</code>，也就是原DES的key的三个，至于key的选取规则，则留给用户遵守</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * DESede ECB 模式加密</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> data 需要加密的数据字符串</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> key  加密的key</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> String <span class="title">des3ECBcrypt</span><span class="params">(<span class="keyword">byte</span>[] data, <span class="keyword">byte</span>[] key)</span> </span>&#123;</span><br><span class="line">    <span class="comment">// 加密结果字节数组</span></span><br><span class="line">    <span class="keyword">byte</span>[] encrypted;</span><br><span class="line">    <span class="comment">// 加密结果字符串</span></span><br><span class="line">    String result = <span class="keyword">null</span>;</span><br><span class="line">    <span class="keyword">if</span> (<span class="keyword">null</span> != key &amp;&amp; key.length != <span class="number">24</span>) &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;DESede uses a key length of 24 bytes (192 bits).&quot;</span>);</span><br><span class="line">        <span class="keyword">return</span> result;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">try</span> &#123;</span><br><span class="line">        <span class="comment">// 实例化 密钥材料</span></span><br><span class="line">        DESedeKeySpec desKey = <span class="keyword">new</span> DESedeKeySpec(key);</span><br><span class="line">        <span class="comment">// 实例化 密钥生成器</span></span><br><span class="line">        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(<span class="string">&quot;DESede&quot;</span>);</span><br><span class="line">        <span class="comment">// 生成密钥</span></span><br><span class="line">        SecretKey secretKey = keyFactory.generateSecret(desKey);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">        <span class="comment">// 指定加密模式 实例化Ciper对象</span></span><br><span class="line">        Cipher cipher = Cipher.getInstance(<span class="string">&quot;DESede/ECB/PKCS5Padding&quot;</span>); <span class="comment">// 加密方式/工作模式/填充模式</span></span><br><span class="line">        <span class="comment">// 初始化,设置加密(1)或解密(2)</span></span><br><span class="line">        cipher.init(Cipher.ENCRYPT_MODE, secretKey);</span><br><span class="line">        <span class="comment">// 执行，得到结果字节数组</span></span><br><span class="line">        encrypted = cipher.doFinal(data);</span><br><span class="line">        <span class="comment">// 对结果字节数组进行base64编码，得到加密后的字符串</span></span><br><span class="line">        result = Base64.getEncoder().encodeToString(encrypted);</span><br><span class="line">    &#125; <span class="keyword">catch</span> (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException | BadPaddingException | IllegalBlockSizeException | InvalidKeySpecException e) &#123;</span><br><span class="line">        e.printStackTrace();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> result;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>其实就是相比DES，将<code>DESKeySpec</code>类替换为<code>DESedeKeySpec</code>类，将字符串<code>DES</code>替换为<code>DESede</code></p>
<p>调用</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">System.out.println(des3ECBcrypt(<span class="string">&quot;Forgo7ten&quot;</span>.getBytes(StandardCharsets.UTF_8), <span class="string">&quot;123456781234567812345678&quot;</span>.getBytes(StandardCharsets.UTF_8)));	<span class="comment">// 由于三个key相同，则加密结果与一个key的DES结果相同</span></span><br></pre></td></tr></table></figure>
<h2 id="AES">AES<a class="header-anchor" href="#AES"> ¶ </a></h2>
<table>
<thead>
<tr>
<th style="text-align:center">AES</th>
<th style="text-align:center">密钥长度(32位比特字)</th>
<th style="text-align:center">分组长度(32位比特字)</th>
<th style="text-align:center">加密轮数</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:center">AES-128</td>
<td style="text-align:center">4(128位)</td>
<td style="text-align:center">4</td>
<td style="text-align:center">10</td>
</tr>
<tr>
<td style="text-align:center">AES-192</td>
<td style="text-align:center">6</td>
<td style="text-align:center">4</td>
<td style="text-align:center">12</td>
</tr>
<tr>
<td style="text-align:center">AES-256</td>
<td style="text-align:center">8</td>
<td style="text-align:center">4</td>
<td style="text-align:center">14</td>
</tr>
</tbody>
</table>
<h3 id="原理-3">原理<a class="header-anchor" href="#原理-3"> ¶ </a></h3>
<p>AES算法是对称密码，主要有四种操作处理，分别是密钥加法层(也叫轮密钥加，英文Add Round Key)、字节代换层(SubByte)、行位移层(Shift Rows)、列混淆层(Mix Column)。</p>
<p>而明文x和密钥k都是由16个字节组成的数据(当然密钥还支持192位和256位的长度，暂时不考虑)，它<strong>是按照字节的先后顺序从上到下、从左到右进行排列的。</strong></p>
<p>AES算法在处理的轮数上只有最后一轮操作与前面的轮处理上有些许不同(最后一轮只是少了列混淆处理)，在轮处理开始前还单独进行了一次轮密钥加的处理。在处理轮数上，我们只考虑128位密钥的10轮处理。</p>
<p><img src= "" data-lazy-src="/AndroidReverse/2022/Learning_about_cryptographic_algorithms/AES-0.jpg" alt="AES-0"></p>
<h4 id="字节代换操作">字节代换操作<a class="header-anchor" href="#字节代换操作"> ¶ </a></h4>
<p>状态矩阵中的元素按照下面的方式映射为一个新的字节：</p>
<p>把该字节的高4位作为行值，低4位作为列值，取出S盒或者逆S盒中对应的行的元素作为输出。</p>
<p>例如，加密时，输出的字节S1为0x12,则查S盒的第0x01行和0x02列，得到值0xc9,然后替换S1原有的0x12为0xc9。</p>
<p>S盒为16*16</p>
<h4 id="行位移操作">行位移操作<a class="header-anchor" href="#行位移操作"> ¶ </a></h4>
<p>行移位是一个简单的左循环移位操作。</p>
<p><img src= "" data-lazy-src="/AndroidReverse/2022/Learning_about_cryptographic_algorithms/AES-1.png" alt="AES-1-行位移加密"></p>
<p>当密钥长度为128比特时，在加密时，保持矩阵的第一行不变，第二行向左移动8Bit(一个字节)、第三行向左移动2个字节、第四行向左移动3个字节。而在解密时恰恰相反，依然保持第一行不变，将第二行向右移动一个字节、第三行右移2个字节、第四行右移3个字节。</p>
<h4 id="列混淆">列混淆<a class="header-anchor" href="#列混淆"> ¶ </a></h4>
<p>列混合变换是通过矩阵相乘来实现的，经行移位后的状态矩阵与固定的<strong>矩阵相乘</strong>，得到混淆后的状态矩阵</p>
<h3 id="实现-4">实现<a class="header-anchor" href="#实现-4"> ¶ </a></h3>
<h4 id="Java-3">Java<a class="header-anchor" href="#Java-3"> ¶ </a></h4>
<script src="https://gist.github.com/Forgo7ten/5c0632182b9d671664f7e73e1c31ec40.js"></script>
<h2 id="TEA系列密码">TEA系列密码<a class="header-anchor" href="#TEA系列密码"> ¶ </a></h2>
<h2 id="SM4算法">SM4算法<a class="header-anchor" href="#SM4算法"> ¶ </a></h2>
<h3 id="SM4算法的特征">SM4算法的特征<a class="header-anchor" href="#SM4算法的特征"> ¶ </a></h3>
<ol>
<li>
<p>S盒固定</p>
 <figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">unsigned</span> <span class="keyword">char</span> TAO[<span class="number">16</span>][<span class="number">16</span>] =</span><br><span class="line">&#123;</span><br><span class="line">    &#123;<span class="number">0xd6</span>,<span class="number">0x90</span>,<span class="number">0xe9</span>,<span class="number">0xfe</span>,<span class="number">0xcc</span>,<span class="number">0xe1</span>,<span class="number">0x3d</span>,<span class="number">0xb7</span>,<span class="number">0x16</span>,<span class="number">0xb6</span>,<span class="number">0x14</span>,<span class="number">0xc2</span>,<span class="number">0x28</span>,<span class="number">0xfb</span>,<span class="number">0x2c</span>,<span class="number">0x05</span>&#125;,</span><br><span class="line">    &#123;<span class="number">0x2b</span>,<span class="number">0x67</span>,<span class="number">0x9a</span>,<span class="number">0x76</span>,<span class="number">0x2a</span>,<span class="number">0xbe</span>,<span class="number">0x04</span>,<span class="number">0xc3</span>,<span class="number">0xaa</span>,<span class="number">0x44</span>,<span class="number">0x13</span>,<span class="number">0x26</span>,<span class="number">0x49</span>,<span class="number">0x86</span>,<span class="number">0x06</span>,<span class="number">0x99</span>&#125;,</span><br><span class="line">    &#123;<span class="number">0x9c</span>,<span class="number">0x42</span>,<span class="number">0x50</span>,<span class="number">0xf4</span>,<span class="number">0x91</span>,<span class="number">0xef</span>,<span class="number">0x98</span>,<span class="number">0x7a</span>,<span class="number">0x33</span>,<span class="number">0x54</span>,<span class="number">0x0b</span>,<span class="number">0x43</span>,<span class="number">0xed</span>,<span class="number">0xcf</span>,<span class="number">0xac</span>,<span class="number">0x62</span>&#125;,</span><br><span class="line">    &#123;<span class="number">0xe4</span>,<span class="number">0xb3</span>,<span class="number">0x1c</span>,<span class="number">0xa9</span>,<span class="number">0xc9</span>,<span class="number">0x08</span>,<span class="number">0xe8</span>,<span class="number">0x95</span>,<span class="number">0x80</span>,<span class="number">0xdf</span>,<span class="number">0x94</span>,<span class="number">0xfa</span>,<span class="number">0x75</span>,<span class="number">0x8f</span>,<span class="number">0x3f</span>,<span class="number">0xa6</span>&#125;,</span><br><span class="line">    &#123;<span class="number">0x47</span>,<span class="number">0x07</span>,<span class="number">0xa7</span>,<span class="number">0xfc</span>,<span class="number">0xf3</span>,<span class="number">0x73</span>,<span class="number">0x17</span>,<span class="number">0xba</span>,<span class="number">0x83</span>,<span class="number">0x59</span>,<span class="number">0x3c</span>,<span class="number">0x19</span>,<span class="number">0xe6</span>,<span class="number">0x85</span>,<span class="number">0x4f</span>,<span class="number">0xa8</span>&#125;,</span><br><span class="line">    &#123;<span class="number">0x68</span>,<span class="number">0x6b</span>,<span class="number">0x81</span>,<span class="number">0xb2</span>,<span class="number">0x71</span>,<span class="number">0x64</span>,<span class="number">0xda</span>,<span class="number">0x8b</span>,<span class="number">0xf8</span>,<span class="number">0xeb</span>,<span class="number">0x0f</span>,<span class="number">0x4b</span>,<span class="number">0x70</span>,<span class="number">0x56</span>,<span class="number">0x9d</span>,<span class="number">0x35</span>&#125;,</span><br><span class="line">    &#123;<span class="number">0x1e</span>,<span class="number">0x24</span>,<span class="number">0x0e</span>,<span class="number">0x5e</span>,<span class="number">0x63</span>,<span class="number">0x58</span>,<span class="number">0xd1</span>,<span class="number">0xa2</span>,<span class="number">0x25</span>,<span class="number">0x22</span>,<span class="number">0x7c</span>,<span class="number">0x3b</span>,<span class="number">0x01</span>,<span class="number">0x21</span>,<span class="number">0x78</span>,<span class="number">0x87</span>&#125;,</span><br><span class="line">    &#123;<span class="number">0xd4</span>,<span class="number">0x00</span>,<span class="number">0x46</span>,<span class="number">0x57</span>,<span class="number">0x9f</span>,<span class="number">0xd3</span>,<span class="number">0x27</span>,<span class="number">0x52</span>,<span class="number">0x4c</span>,<span class="number">0x36</span>,<span class="number">0x02</span>,<span class="number">0xe7</span>,<span class="number">0xa0</span>,<span class="number">0xc4</span>,<span class="number">0xc8</span>,<span class="number">0x9e</span>&#125;,</span><br><span class="line">    &#123;<span class="number">0xea</span>,<span class="number">0xbf</span>,<span class="number">0x8a</span>,<span class="number">0xd2</span>,<span class="number">0x40</span>,<span class="number">0xc7</span>,<span class="number">0x38</span>,<span class="number">0xb5</span>,<span class="number">0xa3</span>,<span class="number">0xf7</span>,<span class="number">0xf2</span>,<span class="number">0xce</span>,<span class="number">0xf9</span>,<span class="number">0x61</span>,<span class="number">0x15</span>,<span class="number">0xa1</span>&#125;,</span><br><span class="line">    &#123;<span class="number">0xe0</span>,<span class="number">0xae</span>,<span class="number">0x5d</span>,<span class="number">0xa4</span>,<span class="number">0x9b</span>,<span class="number">0x34</span>,<span class="number">0x1a</span>,<span class="number">0x55</span>,<span class="number">0xad</span>,<span class="number">0x93</span>,<span class="number">0x32</span>,<span class="number">0x30</span>,<span class="number">0xf5</span>,<span class="number">0x8c</span>,<span class="number">0xb1</span>,<span class="number">0xe3</span>&#125;,</span><br><span class="line">    &#123;<span class="number">0x1d</span>,<span class="number">0xf6</span>,<span class="number">0xe2</span>,<span class="number">0x2e</span>,<span class="number">0x82</span>,<span class="number">0x66</span>,<span class="number">0xca</span>,<span class="number">0x60</span>,<span class="number">0xc0</span>,<span class="number">0x29</span>,<span class="number">0x23</span>,<span class="number">0xab</span>,<span class="number">0x0d</span>,<span class="number">0x53</span>,<span class="number">0x4e</span>,<span class="number">0x6f</span>&#125;,</span><br><span class="line">    &#123;<span class="number">0xd5</span>,<span class="number">0xdb</span>,<span class="number">0x37</span>,<span class="number">0x45</span>,<span class="number">0xde</span>,<span class="number">0xfd</span>,<span class="number">0x8e</span>,<span class="number">0x2f</span>,<span class="number">0x03</span>,<span class="number">0xff</span>,<span class="number">0x6a</span>,<span class="number">0x72</span>,<span class="number">0x6d</span>,<span class="number">0x6c</span>,<span class="number">0x5b</span>,<span class="number">0x51</span>&#125;,</span><br><span class="line">    &#123;<span class="number">0x8d</span>,<span class="number">0x1b</span>,<span class="number">0xaf</span>,<span class="number">0x92</span>,<span class="number">0xbb</span>,<span class="number">0xdd</span>,<span class="number">0xbc</span>,<span class="number">0x7f</span>,<span class="number">0x11</span>,<span class="number">0xd9</span>,<span class="number">0x5c</span>,<span class="number">0x41</span>,<span class="number">0x1f</span>,<span class="number">0x10</span>,<span class="number">0x5a</span>,<span class="number">0xd8</span>&#125;,</span><br><span class="line">    &#123;<span class="number">0x0a</span>,<span class="number">0xc1</span>,<span class="number">0x31</span>,<span class="number">0x88</span>,<span class="number">0xa5</span>,<span class="number">0xcd</span>,<span class="number">0x7b</span>,<span class="number">0xbd</span>,<span class="number">0x2d</span>,<span class="number">0x74</span>,<span class="number">0xd0</span>,<span class="number">0x12</span>,<span class="number">0xb8</span>,<span class="number">0xe5</span>,<span class="number">0xb4</span>,<span class="number">0xb0</span>&#125;,</span><br><span class="line">    &#123;<span class="number">0x89</span>,<span class="number">0x69</span>,<span class="number">0x97</span>,<span class="number">0x4a</span>,<span class="number">0x0c</span>,<span class="number">0x96</span>,<span class="number">0x77</span>,<span class="number">0x7e</span>,<span class="number">0x65</span>,<span class="number">0xb9</span>,<span class="number">0xf1</span>,<span class="number">0x09</span>,<span class="number">0xc5</span>,<span class="number">0x6e</span>,<span class="number">0xc6</span>,<span class="number">0x84</span>&#125;,</span><br><span class="line">    &#123;<span class="number">0x18</span>,<span class="number">0xf0</span>,<span class="number">0x7d</span>,<span class="number">0xec</span>,<span class="number">0x3a</span>,<span class="number">0xdc</span>,<span class="number">0x4d</span>,<span class="number">0x20</span>,<span class="number">0x79</span>,<span class="number">0xee</span>,<span class="number">0x5f</span>,<span class="number">0x3e</span>,<span class="number">0xd7</span>,<span class="number">0xcb</span>,<span class="number">0x39</span>,<span class="number">0x48</span>&#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>
</li>
<li>
<p>系统参数 FK 固定</p>
 <figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">unsigned</span> <span class="keyword">long</span> FK[<span class="number">4</span>] = &#123;<span class="number">0xa3b1bac6</span>, <span class="number">0x56aa3350</span>, <span class="number">0x677d9197</span>, <span class="number">0xb27022dc</span>&#125;;</span><br></pre></td></tr></table></figure>
</li>
<li>
<p>固定参数 CK 固定</p>
 <figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">unsigned</span> <span class="keyword">long</span> CK[<span class="number">32</span>] =</span><br><span class="line">&#123;</span><br><span class="line">    <span class="number">0x00070e15</span>, <span class="number">0x1c232a31</span>, <span class="number">0x383f464d</span>, <span class="number">0x545b6269</span>,</span><br><span class="line">    <span class="number">0x70777e85</span>, <span class="number">0x8c939aa1</span>, <span class="number">0xa8afb6bd</span>, <span class="number">0xc4cbd2d9</span>,</span><br><span class="line">    <span class="number">0xe0e7eef5</span>, <span class="number">0xfc030a11</span>, <span class="number">0x181f262d</span>, <span class="number">0x343b4249</span>,</span><br><span class="line">    <span class="number">0x50575e65</span>, <span class="number">0x6c737a81</span>, <span class="number">0x888f969d</span>, <span class="number">0xa4abb2b9</span>,</span><br><span class="line">    <span class="number">0xc0c7ced5</span>, <span class="number">0xdce3eaf1</span>, <span class="number">0xf8ff060d</span>, <span class="number">0x141b2229</span>,</span><br><span class="line">    <span class="number">0x30373e45</span>, <span class="number">0x4c535a61</span>, <span class="number">0x686f767d</span>, <span class="number">0x848b9299</span>,</span><br><span class="line">    <span class="number">0xa0a7aeb5</span>, <span class="number">0xbcc3cad1</span>, <span class="number">0xd8dfe6ed</span>, <span class="number">0xf4fb0209</span>,</span><br><span class="line">    <span class="number">0x10171e25</span>, <span class="number">0x2c333a41</span>, <span class="number">0x484f565d</span>, <span class="number">0x646b7279</span></span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>
</li>
</ol>
<h3 id="使用python库对SM4算法进行解密">使用python库对SM4算法进行解密<a class="header-anchor" href="#使用python库对SM4算法进行解密"> ¶ </a></h3>
<p>标准128位加密</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">&gt;&gt;&gt; from pysm4 import encrypt, decrypt</span><br><span class="line"># 明文</span><br><span class="line">&gt;&gt;&gt; clear_num = 0x0123456789abcdeffedcba9876543210</span><br><span class="line"># 密钥</span><br><span class="line">&gt;&gt;&gt; mk = 0x0123456789abcdeffedcba9876543210</span><br><span class="line"># 加密</span><br><span class="line">&gt;&gt;&gt; cipher_num = encrypt(clear_num, mk)</span><br><span class="line">&gt;&gt;&gt; hex(cipher_num)[2:].replace(&#x27;L&#x27;, &#x27;&#x27;)</span><br><span class="line">&#x27;681edf34d206965e86b3e94f536e4246&#x27;</span><br><span class="line"># 解密</span><br><span class="line">&gt;&gt;&gt; clear_num == decrypt(cipher_num, mk)</span><br><span class="line">True</span><br></pre></td></tr></table></figure>
<h1 id="非对称密码">非对称密码<a class="header-anchor" href="#非对称密码"> ¶ </a></h1>
<h2 id="RSA">RSA<a class="header-anchor" href="#RSA"> ¶ </a></h2>
<h3 id="基本原理">基本原理<a class="header-anchor" href="#基本原理"> ¶ </a></h3>
<h4 id="前置数学知识">前置数学知识<a class="header-anchor" href="#前置数学知识"> ¶ </a></h4>
<h5 id="互质关系">互质关系<a class="header-anchor" href="#互质关系"> ¶ </a></h5>
<p>如果两个正整数，除了<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn></mrow><annotation encoding="application/x-tex">1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span></span></span></span>以外，没有其他公因子，我们就称这两个数是<em>互质关系</em></p>
<ol>
<li>不是质数也可以构成互质关系，比如<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>15</mn></mrow><annotation encoding="application/x-tex">15</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">15</span></span></span></span>和<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>32</mn></mrow><annotation encoding="application/x-tex">32</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">32</span></span></span></span>。</li>
<li>任意两个质数构成互质关系，比如<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>13</mn></mrow><annotation encoding="application/x-tex">13</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">13</span></span></span></span>和<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>61</mn></mrow><annotation encoding="application/x-tex">61</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">61</span></span></span></span>。</li>
<li>一个数是质数，另一个数只要不是前者的倍数，两者就构成互质关系，比如<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>3</mn></mrow><annotation encoding="application/x-tex">3</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">3</span></span></span></span>和<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>10</mn></mrow><annotation encoding="application/x-tex">10</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">10</span></span></span></span>。</li>
<li>如果两个数之中，较大的那个数是质数，则两者构成互质关系，比如<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>97</mn></mrow><annotation encoding="application/x-tex">97</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">97</span></span></span></span>和<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>57</mn></mrow><annotation encoding="application/x-tex">57</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">57</span></span></span></span>。</li>
<li><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn></mrow><annotation encoding="application/x-tex">1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span></span></span></span>和任意一个自然数是都是互质关系，比如<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn></mrow><annotation encoding="application/x-tex">1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span></span></span></span>和<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>99</mn></mrow><annotation encoding="application/x-tex">99</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">99</span></span></span></span>。</li>
<li><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi></mrow><annotation encoding="application/x-tex">p</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">p</span></span></span></span>是大于<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn></mrow><annotation encoding="application/x-tex">1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span></span></span></span>的整数，则<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi></mrow><annotation encoding="application/x-tex">p</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">p</span></span></span></span>和<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi><mo>−</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">p-1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7778em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">p</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span></span></span></span>构成互质关系，比如<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>57</mn></mrow><annotation encoding="application/x-tex">57</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">57</span></span></span></span>和<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>56</mn></mrow><annotation encoding="application/x-tex">56</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">56</span></span></span></span>。</li>
<li><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi></mrow><annotation encoding="application/x-tex">p</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">p</span></span></span></span>是大于<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn></mrow><annotation encoding="application/x-tex">1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span></span></span></span>的奇数，则<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi></mrow><annotation encoding="application/x-tex">p</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">p</span></span></span></span>和<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi><mo>−</mo><mn>2</mn></mrow><annotation encoding="application/x-tex">p-2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7778em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">p</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">2</span></span></span></span>构成互质关系，比如<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>17</mn></mrow><annotation encoding="application/x-tex">17</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">17</span></span></span></span>和<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>15</mn></mrow><annotation encoding="application/x-tex">15</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">15</span></span></span></span>。</li>
</ol>
<h5 id="欧拉函数">欧拉函数<a class="header-anchor" href="#欧拉函数"> ¶ </a></h5>
<p>任意给定正整数<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span></span></span></span>，在小于等于<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span></span></span></span>的正整数之中，能与<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span></span></span></span>构成互质关系的数 的个数；计算这个值的方法叫做欧拉函数，以<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>φ</mi><mo stretchy="false">(</mo><mi>n</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\varphi (n)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">φ</span><span class="mopen">(</span><span class="mord mathnormal">n</span><span class="mclose">)</span></span></span></span>表示。</p>
<ol>
<li>如果<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mo>=</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">n=1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span></span></span></span>，则 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>φ</mi><mo stretchy="false">(</mo><mn>1</mn><mo stretchy="false">)</mo><mo>=</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">\varphi(1) = 1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">φ</span><span class="mopen">(</span><span class="mord">1</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span></span></span></span> 。因为1与任何数（包括自身）都构成互质关系</li>
<li><strong>如果n是质数，则 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>φ</mi><mo stretchy="false">(</mo><mn>1</mn><mo stretchy="false">)</mo><mo>=</mo><mi>n</mi><mo>−</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">\varphi(1) = n-1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">φ</span><span class="mopen">(</span><span class="mord">1</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6667em;vertical-align:-0.0833em;"></span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span></span></span></span> 。因为质数与小于它的每一个数，都构成互质关系</strong></li>
<li>如果n是质数的某一个次方，即 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mo>=</mo><msup><mi>p</mi><mi>k</mi></msup></mrow><annotation encoding="application/x-tex">n = p^k</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1.0435em;vertical-align:-0.1944em;"></span><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8491em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span></span></span></span></span></span></span></span> (<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi></mrow><annotation encoding="application/x-tex">p</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">p</span></span></span></span>为质数，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi></mrow><annotation encoding="application/x-tex">k</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span></span></span></span>为大于等于<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn></mrow><annotation encoding="application/x-tex">1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span></span></span></span>的整数)，则<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>φ</mi><mo stretchy="false">(</mo><msup><mi>p</mi><mi>k</mi></msup><mo stretchy="false">)</mo><mo>=</mo><msup><mi>p</mi><mi>k</mi></msup><mo>−</mo><msup><mi>p</mi><mrow><mi>k</mi><mo>−</mo><mn>1</mn></mrow></msup></mrow><annotation encoding="application/x-tex">\varphi(p^k) = p^k - p^{k-1}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.0991em;vertical-align:-0.25em;"></span><span class="mord mathnormal">φ</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8491em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1.0435em;vertical-align:-0.1944em;"></span><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8491em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1.0435em;vertical-align:-0.1944em;"></span><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8491em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span></span></span></span>；也可以写成<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>φ</mi><mo stretchy="false">(</mo><msup><mi>p</mi><mi>k</mi></msup><mo stretchy="false">)</mo><mo>=</mo><msup><mi>p</mi><mi>k</mi></msup><mo>−</mo><msup><mi>p</mi><mrow><mi>k</mi><mo>−</mo><mn>1</mn></mrow></msup><mo>=</mo><msup><mi>p</mi><mi>k</mi></msup><mo stretchy="false">(</mo><mn>1</mn><mo>−</mo><mfrac><mn>1</mn><mi>p</mi></mfrac><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\varphi(p^k)=p^k-p^{k-1}=p^k(1-\frac1p)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.0991em;vertical-align:-0.25em;"></span><span class="mord mathnormal">φ</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8491em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1.0435em;vertical-align:-0.1944em;"></span><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8491em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1.0435em;vertical-align:-0.1944em;"></span><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8491em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1.0991em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8491em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1.3262em;vertical-align:-0.4811em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8451em;"><span style="top:-2.655em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">p</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.4811em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose">)</span></span></span></span></li>
<li><strong>如果n可以分解成两个互质的整数之积，即<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mo>=</mo><mi>p</mi><mn>1</mn><mo>×</mo><mi>p</mi><mn>2</mn></mrow><annotation encoding="application/x-tex">n = p1 \times p2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.8389em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">p</span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.8389em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">p</span><span class="mord">2</span></span></span></span>；则 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>φ</mi><mo stretchy="false">(</mo><mi>n</mi><mo stretchy="false">)</mo><mo>=</mo><mi>φ</mi><mo stretchy="false">(</mo><mi>p</mi><mn>1</mn><mo>×</mo><mi>p</mi><mn>2</mn><mo stretchy="false">)</mo><mo>=</mo><mi>φ</mi><mo stretchy="false">(</mo><mi>p</mi><mn>1</mn><mo stretchy="false">)</mo><mo>×</mo><mi>φ</mi><mo stretchy="false">(</mo><mi>p</mi><mn>2</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\varphi(n) = \varphi(p1 \times p2) = \varphi(p1) \times \varphi(p2)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">φ</span><span class="mopen">(</span><span class="mord mathnormal">n</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">φ</span><span class="mopen">(</span><span class="mord mathnormal">p</span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">p</span><span class="mord">2</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">φ</span><span class="mopen">(</span><span class="mord mathnormal">p</span><span class="mord">1</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">φ</span><span class="mopen">(</span><span class="mord mathnormal">p</span><span class="mord">2</span><span class="mclose">)</span></span></span></span>，即积的欧拉函数等于各个因子的欧拉函数之积。</strong></li>
</ol>
<h5 id="欧拉定理">欧拉定理<a class="header-anchor" href="#欧拉定理"> ¶ </a></h5>
<p>如果两个正整数a和n互质，则n的欧拉函数 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>φ</mi><mo stretchy="false">(</mo><mi>n</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\varphi (n)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">φ</span><span class="mopen">(</span><span class="mord mathnormal">n</span><span class="mclose">)</span></span></span></span> 可以让下面的等式成立：</p>
<p><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>a</mi><mrow><mi>φ</mi><mo stretchy="false">(</mo><mi>n</mi><mo stretchy="false">)</mo></mrow></msup><mo>≡</mo><mn>1</mn><mspace></mspace><mspace width="0.4444em"><mo stretchy="false">(</mo><mrow><mi mathvariant="normal">m</mi><mi mathvariant="normal">o</mi><mi mathvariant="normal">d</mi></mrow><mspace width="0.3333em"><mi>n</mi><mo stretchy="false">)</mo></mspace></mspace></mrow><annotation encoding="application/x-tex">a^{\varphi(n)} \equiv 1\pmod n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.888em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.888em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">φ</span><span class="mopen mtight">(</span><span class="mord mathnormal mtight">n</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">≡</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span><span class="mspace allowbreak"></span><span class="mspace" style="margin-right:0.4444em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord"><span class="mord mathrm">mod</span></span></span><span class="mspace" style="margin-right:0.3333em;"></span><span class="mord mathnormal">n</span><span class="mclose">)</span></span></span></span></p>
<p>也就是说，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi></mrow><annotation encoding="application/x-tex">a</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">a</span></span></span></span>的<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>φ</mi><mo stretchy="false">(</mo><mi>n</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\varphi(n)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">φ</span><span class="mopen">(</span><span class="mord mathnormal">n</span><span class="mclose">)</span></span></span></span>次方除以<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span></span></span></span>的余数为1。</p>
<p><strong>费马小定理：</strong><br>
假设正整数<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi></mrow><annotation encoding="application/x-tex">a</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">a</span></span></span></span>与质数<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi></mrow><annotation encoding="application/x-tex">p</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">p</span></span></span></span>互质，因为质数p的 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>φ</mi><mo stretchy="false">(</mo><mi>p</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\varphi (p)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">φ</span><span class="mopen">(</span><span class="mord mathnormal">p</span><span class="mclose">)</span></span></span></span> 等于<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi><mo>−</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">p-1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7778em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">p</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span></span></span></span>，则欧拉定理可以写成</p>
<p><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>a</mi><mrow><mi>p</mi><mo>−</mo><mn>1</mn></mrow></msup><mo>≡</mo><mn>1</mn><mspace></mspace><mspace width="0.4444em"><mo stretchy="false">(</mo><mrow><mi mathvariant="normal">m</mi><mi mathvariant="normal">o</mi><mi mathvariant="normal">d</mi></mrow><mspace width="0.3333em"><mi>p</mi><mo stretchy="false">)</mo></mspace></mspace></mrow><annotation encoding="application/x-tex">a^{p-1} \equiv 1\pmod p</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">p</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">≡</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span><span class="mspace allowbreak"></span><span class="mspace" style="margin-right:0.4444em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord"><span class="mord mathrm">mod</span></span></span><span class="mspace" style="margin-right:0.3333em;"></span><span class="mord mathnormal">p</span><span class="mclose">)</span></span></span></span></p>
<h5 id="模反元素">模反元素<a class="header-anchor" href="#模反元素"> ¶ </a></h5>
<p>如果两个正整数<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi></mrow><annotation encoding="application/x-tex">a</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">a</span></span></span></span>和<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span></span></span></span>互质，那么一定可以找到整数<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>b</mi></mrow><annotation encoding="application/x-tex">b</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">b</span></span></span></span>，使得 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi><mi>b</mi><mo>−</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">ab-1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7778em;vertical-align:-0.0833em;"></span><span class="mord mathnormal">ab</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span></span></span></span> 被<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span></span></span></span>整除，或者说<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi><mi>b</mi></mrow><annotation encoding="application/x-tex">ab</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">ab</span></span></span></span>除以<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span></span></span></span>的余数是<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn></mrow><annotation encoding="application/x-tex">1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span></span></span></span>。<br>
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi><mi>b</mi><mo>≡</mo><mn>1</mn><mspace></mspace><mspace width="0.4444em"><mo stretchy="false">(</mo><mrow><mi mathvariant="normal">m</mi><mi mathvariant="normal">o</mi><mi mathvariant="normal">d</mi></mrow><mspace width="0.3333em"><mi>n</mi><mo stretchy="false">)</mo></mspace></mspace></mrow><annotation encoding="application/x-tex">ab \equiv 1\pmod n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">ab</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">≡</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span><span class="mspace allowbreak"></span><span class="mspace" style="margin-right:0.4444em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord"><span class="mord mathrm">mod</span></span></span><span class="mspace" style="margin-right:0.3333em;"></span><span class="mord mathnormal">n</span><span class="mclose">)</span></span></span></span><br>
这时候b就叫做a的&quot;模反元素&quot;。</p>
<p>而<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>a</mi><mrow><mi>φ</mi><mo stretchy="false">(</mo><mi>n</mi><mo stretchy="false">)</mo></mrow></msup><mo>=</mo><mi>a</mi><mo>×</mo><msup><mi>a</mi><mrow><mi>φ</mi><mo stretchy="false">(</mo><mi>n</mi><mo stretchy="false">)</mo><mo>−</mo><mn>1</mn></mrow></msup><mo>≡</mo><mn>1</mn><mspace></mspace><mspace width="0.4444em"><mo stretchy="false">(</mo><mrow><mi mathvariant="normal">m</mi><mi mathvariant="normal">o</mi><mi mathvariant="normal">d</mi></mrow><mspace width="0.3333em"><mi>n</mi><mo stretchy="false">)</mo></mspace></mspace></mrow><annotation encoding="application/x-tex">a^{\varphi(n)}=a\times a^{\varphi(n)-1}\equiv 1\pmod n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.888em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.888em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">φ</span><span class="mopen mtight">(</span><span class="mord mathnormal mtight">n</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6667em;vertical-align:-0.0833em;"></span><span class="mord mathnormal">a</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.888em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.888em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">φ</span><span class="mopen mtight">(</span><span class="mord mathnormal mtight">n</span><span class="mclose mtight">)</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">≡</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span><span class="mspace allowbreak"></span><span class="mspace" style="margin-right:0.4444em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord"><span class="mord mathrm">mod</span></span></span><span class="mspace" style="margin-right:0.3333em;"></span><span class="mord mathnormal">n</span><span class="mclose">)</span></span></span></span>，可以得到<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>a</mi><mrow><mi>φ</mi><mo stretchy="false">(</mo><mi>n</mi><mo stretchy="false">)</mo><mo>−</mo><mn>1</mn></mrow></msup></mrow><annotation encoding="application/x-tex">a^{\varphi(n)-1}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.888em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.888em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">φ</span><span class="mopen mtight">(</span><span class="mord mathnormal mtight">n</span><span class="mclose mtight">)</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span></span></span></span>就是<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi></mrow><annotation encoding="application/x-tex">a</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">a</span></span></span></span>的模反元素。</p>
<h4 id="公钥与私钥的产生">公钥与私钥的产生<a class="header-anchor" href="#公钥与私钥的产生"> ¶ </a></h4>
<ol>
<li>随机选择两个不相等大质数 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi></mrow><annotation encoding="application/x-tex">p</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">p</span></span></span></span> 和 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>q</mi></mrow><annotation encoding="application/x-tex">q</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">q</span></span></span></span>，计算 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>N</mi><mo>=</mo><mi>p</mi><mo>×</mo><mi>q</mi></mrow><annotation encoding="application/x-tex">N = p \times q</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.7778em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">p</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">q</span></span></span></span></li>
<li>根据欧拉函数，求得<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>N</mi></mrow><annotation encoding="application/x-tex">N</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span></span></span></span>的欧拉函数： <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>φ</mi><mo stretchy="false">(</mo><mi>N</mi><mo stretchy="false">)</mo><mo>=</mo><mi>φ</mi><mo stretchy="false">(</mo><mi>p</mi><mo stretchy="false">)</mo><mi>φ</mi><mo stretchy="false">(</mo><mi>q</mi><mo stretchy="false">)</mo><mo>=</mo><mo stretchy="false">(</mo><mi>p</mi><mo>−</mo><mn>1</mn><mo stretchy="false">)</mo><mo stretchy="false">(</mo><mi>q</mi><mo>−</mo><mn>1</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\varphi (N)=\varphi (p)\varphi (q)=(p-1)(q-1)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">φ</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">φ</span><span class="mopen">(</span><span class="mord mathnormal">p</span><span class="mclose">)</span><span class="mord mathnormal">φ</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.03588em;">q</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">p</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">1</span><span class="mclose">)</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.03588em;">q</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">1</span><span class="mclose">)</span></span></span></span> [^rsa  公钥与私钥的产生-2]</li>
<li>选择一个小于 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>φ</mi><mo stretchy="false">(</mo><mi>N</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\varphi (N)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">φ</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span><span class="mclose">)</span></span></span></span> 的整数 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>e</mi></mrow><annotation encoding="application/x-tex">e</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">e</span></span></span></span>（<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>e</mi></mrow><annotation encoding="application/x-tex">e</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">e</span></span></span></span>需满足 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><mo>&lt;</mo><mi>e</mi><mo>&lt;</mo><mi>φ</mi><mo stretchy="false">(</mo><mi>N</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">1&lt;e&lt;\varphi (N)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6835em;vertical-align:-0.0391em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">&lt;</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.5782em;vertical-align:-0.0391em;"></span><span class="mord mathnormal">e</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">&lt;</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">φ</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span><span class="mclose">)</span></span></span></span> 且 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>e</mi></mrow><annotation encoding="application/x-tex">e</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">e</span></span></span></span> 和 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>φ</mi><mo stretchy="false">(</mo><mi>N</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\varphi (N)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">φ</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span><span class="mclose">)</span></span></span></span> 互质；实际应用中，常常选择<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>65537</mn></mrow><annotation encoding="application/x-tex">65537</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">65537</span></span></span></span>）。并求得 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>e</mi></mrow><annotation encoding="application/x-tex">e</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">e</span></span></span></span> 关于 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>φ</mi><mo stretchy="false">(</mo><mi>N</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\varphi (N)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">φ</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span><span class="mclose">)</span></span></span></span> 的模反元素，命名为 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>d</mi></mrow><annotation encoding="application/x-tex">d</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">d</span></span></span></span>，有 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>e</mi><mi>d</mi><mo>≡</mo><mn>1</mn><mspace></mspace><mspace width="0.4444em"><mo stretchy="false">(</mo><mrow><mi mathvariant="normal">m</mi><mi mathvariant="normal">o</mi><mi mathvariant="normal">d</mi></mrow><mspace width="0.3333em"><mi>φ</mi><mo stretchy="false">(</mo><mi>N</mi><mo stretchy="false">)</mo><mo stretchy="false">)</mo></mspace></mspace></mrow><annotation encoding="application/x-tex">ed\equiv 1 \pmod {\varphi (N)}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">e</span><span class="mord mathnormal">d</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">≡</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span><span class="mspace allowbreak"></span><span class="mspace" style="margin-right:0.4444em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord"><span class="mord mathrm">mod</span></span></span><span class="mspace" style="margin-right:0.3333em;"></span><span class="mord mathnormal">φ</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span><span class="mclose">))</span></span></span></span></li>
<li>将 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi></mrow><annotation encoding="application/x-tex">p</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">p</span></span></span></span> 和 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>q</mi></mrow><annotation encoding="application/x-tex">q</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">q</span></span></span></span> 的记录销毁</li>
</ol>
<p>此时，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>N</mi><mo separator="true">,</mo><mi>e</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(N,e)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord mathnormal">e</span><span class="mclose">)</span></span></span></span> 是公钥，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>N</mi><mo separator="true">,</mo><mi>d</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(N,d)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord mathnormal">d</span><span class="mclose">)</span></span></span></span> 是私钥，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>N</mi><mo separator="true">,</mo><mi>e</mi><mo separator="true">,</mo><mi>d</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(N,e,d)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord mathnormal">e</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord mathnormal">d</span><span class="mclose">)</span></span></span></span>是密钥对。</p>
<p>[^rsa  公钥与私钥的产生-2]: 根据前置数学知识的欧拉函数[4]可知<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>φ</mi><mo stretchy="false">(</mo><mi>N</mi><mo stretchy="false">)</mo><mo>=</mo><mi>φ</mi><mo stretchy="false">(</mo><mi>p</mi><mo stretchy="false">)</mo><mi>φ</mi><mo stretchy="false">(</mo><mi>q</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\varphi (N)=\varphi (p)\varphi (q)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">φ</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">φ</span><span class="mopen">(</span><span class="mord mathnormal">p</span><span class="mclose">)</span><span class="mord mathnormal">φ</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.03588em;">q</span><span class="mclose">)</span></span></span></span>​，由[2]可知<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>φ</mi><mo stretchy="false">(</mo><mi>p</mi><mo stretchy="false">)</mo><mi>φ</mi><mo stretchy="false">(</mo><mi>q</mi><mo stretchy="false">)</mo><mo>=</mo><mo stretchy="false">(</mo><mi>p</mi><mo>−</mo><mn>1</mn><mo stretchy="false">)</mo><mo stretchy="false">(</mo><mi>q</mi><mo>−</mo><mn>1</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\varphi (p)\varphi (q)=(p-1)(q-1)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">φ</span><span class="mopen">(</span><span class="mord mathnormal">p</span><span class="mclose">)</span><span class="mord mathnormal">φ</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.03588em;">q</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">p</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">1</span><span class="mclose">)</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.03588em;">q</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">1</span><span class="mclose">)</span></span></span></span>​</p>
<p>产生的公钥和私钥均可用于加解密操作，用公钥加密的数据只能由对应的私钥解密，反之亦然。一般常用于以下两种途径：</p>
<ul>
<li>私钥用于签名，公钥用于验签。</li>
<li>公钥用于加密、私钥用于解密。</li>
</ul>
<h4 id="消息加密">消息加密<a class="header-anchor" href="#消息加密"> ¶ </a></h4>
<p>首先需要将消息 以一个双方约定好的格式转化为一个小于 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>N</mi></mrow><annotation encoding="application/x-tex">N</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span></span></span></span>，且与 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>N</mi></mrow><annotation encoding="application/x-tex">N</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span></span></span></span> 互质的整数 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi></mrow><annotation encoding="application/x-tex">m</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">m</span></span></span></span>。如果消息太长，可以将消息分为几段，这也就是我们所说的块加密，后对于每一部分利用如下公式加密：</p>
<p><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msup><mi>m</mi><mi>e</mi></msup><mo>≡</mo><mi>c</mi><mspace></mspace><mspace width="1em"><mo stretchy="false">(</mo><mrow><mi mathvariant="normal">m</mi><mi mathvariant="normal">o</mi><mi mathvariant="normal">d</mi></mrow><mspace width="0.3333em"><mi>N</mi><mo stretchy="false">)</mo></mspace></mspace></mrow><annotation encoding="application/x-tex">m^{e}\equiv c\pmod N
</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7144em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7144em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">e</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">≡</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">c</span><span class="mspace allowbreak"></span><span class="mspace" style="margin-right:1em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord"><span class="mord mathrm">mod</span></span></span><span class="mspace" style="margin-right:0.3333em;"></span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span><span class="mclose">)</span></span></span></span></span></p>
<h4 id="消息解密">消息解密<a class="header-anchor" href="#消息解密"> ¶ </a></h4>
<p>利用密钥 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>d</mi></mrow><annotation encoding="application/x-tex">d</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">d</span></span></span></span> 进行解密。</p>
<p><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msup><mi>c</mi><mi>d</mi></msup><mo>≡</mo><mi>m</mi><mspace></mspace><mspace width="1em"><mo stretchy="false">(</mo><mrow><mi mathvariant="normal">m</mi><mi mathvariant="normal">o</mi><mi mathvariant="normal">d</mi></mrow><mspace width="0.3333em"><mi>N</mi><mo stretchy="false">)</mo></mspace></mspace></mrow><annotation encoding="application/x-tex">c^{d}\equiv m\pmod N
</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8991em;"></span><span class="mord"><span class="mord mathnormal">c</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8991em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">d</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">≡</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">m</span><span class="mspace allowbreak"></span><span class="mspace" style="margin-right:1em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord"><span class="mord mathrm">mod</span></span></span><span class="mspace" style="margin-right:0.3333em;"></span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span><span class="mclose">)</span></span></span></span></span></p>
<h3 id="举例">举例<a class="header-anchor" href="#举例"> ¶ </a></h3>
<h4 id="私钥公钥的产生">私钥公钥的产生<a class="header-anchor" href="#私钥公钥的产生"> ¶ </a></h4>
<ol>
<li>
<p>选择两个质数：选择<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>61</mn></mrow><annotation encoding="application/x-tex">61</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">61</span></span></span></span>和<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>53</mn></mrow><annotation encoding="application/x-tex">53</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">53</span></span></span></span></p>
</li>
<li>
<p>计算pq的乘积n：<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mo>=</mo><mn>61</mn><mo>×</mo><mn>53</mn><mo>=</mo><mn>3233</mn></mrow><annotation encoding="application/x-tex">n = 61\times 53 = 3233</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.7278em;vertical-align:-0.0833em;"></span><span class="mord">61</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">53</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">3233</span></span></span></span>；n的长度就是密钥长度。3233写成二进制是<code>110010100001</code>，一共有12位，所以这个密钥就是12位。实际应用中，RSA密钥一般是1024位，重要场合则为2048位。</p>
</li>
<li>
<p>计算n的欧拉函数 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>φ</mi><mo stretchy="false">(</mo><mi>n</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\varphi (n)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">φ</span><span class="mopen">(</span><span class="mord mathnormal">n</span><span class="mclose">)</span></span></span></span>  <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>φ</mi><mo stretchy="false">(</mo><mn>3233</mn><mo stretchy="false">)</mo><mo>=</mo><mo stretchy="false">(</mo><mn>61</mn><mo>−</mo><mn>1</mn><mo stretchy="false">)</mo><mo>×</mo><mo stretchy="false">(</mo><mn>53</mn><mo>−</mo><mn>1</mn><mo stretchy="false">)</mo><mo>=</mo><mn>60</mn><mo>×</mo><mn>52</mn><mo>=</mo><mn>3120</mn></mrow><annotation encoding="application/x-tex">\varphi (3233) = (61-1)\times(53-1) = 60\times52 = 3120</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">φ</span><span class="mopen">(</span><span class="mord">3233</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">61</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">1</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">53</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">1</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.7278em;vertical-align:-0.0833em;"></span><span class="mord">60</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">52</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">3120</span></span></span></span></p>
</li>
<li>
<p>选取整数<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>e</mi></mrow><annotation encoding="application/x-tex">e</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">e</span></span></span></span>，选择为<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>17</mn></mrow><annotation encoding="application/x-tex">17</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">17</span></span></span></span></p>
</li>
<li>
<p>计算e对于  <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>φ</mi><mo stretchy="false">(</mo><mi>n</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\varphi (n)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">φ</span><span class="mopen">(</span><span class="mord mathnormal">n</span><span class="mclose">)</span></span></span></span> 的模反元素d</p>
<p>也就是使得<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>e</mi><mi>d</mi><mo>≡</mo><mn>1</mn><mspace></mspace><mspace width="0.4444em"><mo stretchy="false">(</mo><mrow><mi mathvariant="normal">m</mi><mi mathvariant="normal">o</mi><mi mathvariant="normal">d</mi></mrow><mspace width="0.3333em"><mi>φ</mi><mo stretchy="false">(</mo><mi>n</mi><mo stretchy="false">)</mo><mo stretchy="false">)</mo></mspace></mspace></mrow><annotation encoding="application/x-tex">ed \equiv 1\pmod {\varphi(n)}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">e</span><span class="mord mathnormal">d</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">≡</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span><span class="mspace allowbreak"></span><span class="mspace" style="margin-right:0.4444em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord"><span class="mord mathrm">mod</span></span></span><span class="mspace" style="margin-right:0.3333em;"></span><span class="mord mathnormal">φ</span><span class="mopen">(</span><span class="mord mathnormal">n</span><span class="mclose">))</span></span></span></span>成立，等价于<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>e</mi><mi>d</mi><mo>−</mo><mn>1</mn><mo>=</mo><mi>k</mi><mi>φ</mi><mo stretchy="false">(</mo><mi>n</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">ed-1 = k\varphi(n)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7778em;vertical-align:-0.0833em;"></span><span class="mord mathnormal">e</span><span class="mord mathnormal">d</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mord mathnormal">φ</span><span class="mopen">(</span><span class="mord mathnormal">n</span><span class="mclose">)</span></span></span></span></p>
<p>已知<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>e</mi><mo>=</mo><mn>17</mn></mrow><annotation encoding="application/x-tex">e=17</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">e</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">17</span></span></span></span>，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>φ</mi><mo stretchy="false">(</mo><mi>n</mi><mo stretchy="false">)</mo><mo>=</mo><mn>3120</mn></mrow><annotation encoding="application/x-tex">\varphi(n)=3120</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">φ</span><span class="mopen">(</span><span class="mord mathnormal">n</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">3120</span></span></span></span>，也就是<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>17</mn><mi>d</mi><mo>+</mo><mn>3120</mn><mi>k</mi><mo>=</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">17d+3120k = 1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7778em;vertical-align:-0.0833em;"></span><span class="mord">17</span><span class="mord mathnormal">d</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord">3120</span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span></span></span></span>成立，通过<em>拓展欧几里得算法</em>求得一组解为<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>d</mi><mo separator="true">,</mo><mi>k</mi><mo stretchy="false">)</mo><mo>=</mo><mo stretchy="false">(</mo><mn>2753</mn><mo separator="true">,</mo><mo>−</mo><mn>15</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(d,k) = (2753,-15)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">d</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">2753</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">−</span><span class="mord">15</span><span class="mclose">)</span></span></span></span>，即<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>d</mi><mo>=</mo><mn>2753</mn></mrow><annotation encoding="application/x-tex">d=2753</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">d</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">2753</span></span></span></span></p>
</li>
<li>
<p>封装公钥和私钥</p>
<p>公钥为<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>n</mi><mo separator="true">,</mo><mi>e</mi><mo stretchy="false">)</mo><mo>=</mo><mo stretchy="false">(</mo><mn>3233</mn><mo separator="true">,</mo><mn>17</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(n,e) = (3233, 17)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">n</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord mathnormal">e</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">3233</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">17</span><span class="mclose">)</span></span></span></span>；私钥为<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>n</mi><mo separator="true">,</mo><mi>d</mi><mo stretchy="false">)</mo><mo>=</mo><mo stretchy="false">(</mo><mn>3233</mn><mo separator="true">,</mo><mn>2753</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(n,d) = (3233, 2753)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">n</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord mathnormal">d</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">3233</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">2753</span><span class="mclose">)</span></span></span></span></p>
</li>
</ol>
<h4 id="破解">破解<a class="header-anchor" href="#破解"> ¶ </a></h4>
<p>已知<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span></span></span></span>和<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>e</mi></mrow><annotation encoding="application/x-tex">e</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">e</span></span></span></span>，推导出<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>d</mi></mrow><annotation encoding="application/x-tex">d</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">d</span></span></span></span></p>
<ol>
<li>根据<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>e</mi><mi>d</mi><mo>≡</mo><mn>1</mn><mspace></mspace><mspace width="0.4444em"><mo stretchy="false">(</mo><mrow><mi mathvariant="normal">m</mi><mi mathvariant="normal">o</mi><mi mathvariant="normal">d</mi></mrow><mspace width="0.3333em"><mi>φ</mi><mo stretchy="false">(</mo><mi>N</mi><mo stretchy="false">)</mo><mo stretchy="false">)</mo></mspace></mspace></mrow><annotation encoding="application/x-tex">ed\equiv 1 \pmod {\varphi (N)}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6944em;"></span><span class="mord mathnormal">e</span><span class="mord mathnormal">d</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">≡</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span><span class="mspace allowbreak"></span><span class="mspace" style="margin-right:0.4444em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord"><span class="mord mathrm">mod</span></span></span><span class="mspace" style="margin-right:0.3333em;"></span><span class="mord mathnormal">φ</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span><span class="mclose">))</span></span></span></span>：只有知道<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>e</mi></mrow><annotation encoding="application/x-tex">e</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">e</span></span></span></span>和$ \varphi (N) <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mtext>，才能算出</mtext></mrow><annotation encoding="application/x-tex">，才能算出</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord cjk_fallback">，才能算出</span></span></span></span>d$</li>
<li>而<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>φ</mi><mo stretchy="false">(</mo><mi>N</mi><mo stretchy="false">)</mo><mo>=</mo><mo stretchy="false">(</mo><mi>p</mi><mo>−</mo><mn>1</mn><mo stretchy="false">)</mo><mo stretchy="false">(</mo><mi>q</mi><mo>−</mo><mn>1</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\varphi (N)=(p-1)(q-1)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">φ</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">p</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">1</span><span class="mclose">)</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.03588em;">q</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">1</span><span class="mclose">)</span></span></span></span>：只有知道<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi></mrow><annotation encoding="application/x-tex">p</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">p</span></span></span></span>和<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>q</mi></mrow><annotation encoding="application/x-tex">q</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">q</span></span></span></span>，才能算出$ \varphi (N) $</li>
<li>而<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mo>=</mo><mi>p</mi><mi>q</mi></mrow><annotation encoding="application/x-tex">n=pq</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">pq</span></span></span></span>。只有将<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.4306em;"></span><span class="mord mathnormal">n</span></span></span></span>因数分解，才能算出<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi></mrow><annotation encoding="application/x-tex">p</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">p</span></span></span></span>和<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>q</mi></mrow><annotation encoding="application/x-tex">q</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.1944em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">q</span></span></span></span></li>
</ol>
<p><strong>如果n可以被因数分解，d就可以算出，也就意味着私钥被破解。</strong></p>
<h3 id="实现-5">实现<a class="header-anchor" href="#实现-5"> ¶ </a></h3>
<h4 id="Java-4">Java<a class="header-anchor" href="#Java-4"> ¶ </a></h4>
<p><strong>java的代码中的private key必须使用pkcs#8格式的</strong></p>
<p>密钥格式：</p>
<ul>
<li>PKCS#8：<code>-----BEGIN PRIVATE KEY-----</code> （JAVA格式）</li>
<li>PKCS#1：<code>-----BEGIN RSA PRIVATE KEY-----</code> （JAVA不支持）</li>
</ul>
<script src="https://gist.github.com/Forgo7ten/0a8e003562f9f2576dcddbfed1b79d77.js"></script>
<p>学习更多</p>
<ul>
<li><a target="_blank" rel="noopener" href="https://blog.csdn.net/moakun/article/details/120812061">Java RSA私钥的格式pkcs1和pkcs8、PrivateKey转换_茅坤宝骏氹的博客-CSDN博客</a></li>
</ul>
<h3 id="工具">工具<a class="header-anchor" href="#工具"> ¶ </a></h3>
<h3 id="RSAtool">RSAtool<a class="header-anchor" href="#RSAtool"> ¶ </a></h3>
<ul>
<li>
<p>安装</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">git clone https://github.com/ius/rsatool.git</span><br><span class="line">cd rsatool</span><br><span class="line">python rsatool.py -h</span><br></pre></td></tr></table></figure>
</li>
<li>
<p>生成私钥</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">python rsatool.py -f PEM -o private.pem -p 1234567 -q 7654321</span><br></pre></td></tr></table></figure>
</li>
</ul>
<h4 id="RSA-Converter">RSA Converter<a class="header-anchor" href="#RSA-Converter"> ¶ </a></h4>
<ul>
<li>根据给定密钥对，生成 pem 文件</li>
<li>根据 nn，ee，dd 得出 pp，qq</li>
</ul>
<h4 id="openssl">openssl<a class="header-anchor" href="#openssl"> ¶ </a></h4>
<ul>
<li>
<p>查看公钥文件</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">openssl rsa -pubin -in pubkey.pem -text -modulus</span><br></pre></td></tr></table></figure>
</li>
<li>
<p>解密</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">rsautl -decrypt -inkey private.pem -in flag.enc -out flag</span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>更加具体的细节请参考 <code>openssl --help</code>。</p>
<h4 id="分解整数工具">分解整数工具<a class="header-anchor" href="#分解整数工具"> ¶ </a></h4>
<ul>
<li>
<p>网站分解，<a target="_blank" rel="noopener" href="http://factordb.com/">factor.db</a></p>
</li>
<li>
<p>命令行分解，<a target="_blank" rel="noopener" href="https://github.com/ryosan-470/factordb-pycli">factordb-pycli</a>，借用 factordb 数据库。</p>
</li>
<li>
<p><a target="_blank" rel="noopener" href="https://sourceforge.net/projects/yafu/">yafu</a></p>
<p>使用：</p>
<ol>
<li>进入yafu解压目录，打开cmd命令行</li>
<li>输入<code>yafu-x64</code>（即yafu64位文件名）<br>
命令：<code>factor(n)</code>—— n 为需要分解的大数</li>
</ol>
<p>若n位数过长,将n值保存在文本文档里，最后<strong>一定要有换行符</strong></p>
<figure class="highlight cmd"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">yafu-x64 &quot;factor(@)&quot; -batchfile test.txt</span><br></pre></td></tr></table></figure>
<p>其中<code>test.txt</code>为保存需分解的大质数的文本文档</p>
</li>
</ul>
<h4 id="python库">python库<a class="header-anchor" href="#python库"> ¶ </a></h4>
<h5 id="primefac">primefac<a class="header-anchor" href="#primefac"> ¶ </a></h5>
<p>整数分解库，包含了很多整数分解的算法。</p>
<h5 id="gmpy">gmpy<a class="header-anchor" href="#gmpy"> ¶ </a></h5>
<ul>
<li><code>gmpy.root(a, b)</code>，返回一个元组 <code>(x, y)</code>，其中 <code>x</code> 为 <code>a</code> 开 <code>b</code> 次方的值，<code>y</code> 是判断 <code>x</code> 是否为整数的布尔型变量</li>
</ul>
<h5 id="gmpy2">gmpy2<a class="header-anchor" href="#gmpy2"> ¶ </a></h5>
<p>安装时，可能会需要自己另行安装 mpfr 与 mpc 库。</p>
<ul>
<li><code>gmpy2.iroot(a, b)</code>，类似于 <code>gmpy.root(a,b)</code></li>
</ul>
<blockquote>
<p>安装命令：</p>
  <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">python -m pip install gmpy2</span><br></pre></td></tr></table></figure>
</blockquote>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> gmpy2</span><br><span class="line">N = <span class="number">103461035900816914121390101299049044413950405173712170434161686539878160984549</span></span><br><span class="line">E = <span class="number">65537</span></span><br><span class="line">p = <span class="number">282164587459512124844245113950593348271</span></span><br><span class="line">q = <span class="number">366669102002966856876605669837014229419</span></span><br><span class="line">L = (p-<span class="number">1</span>)*(q-<span class="number">1</span>)</span><br><span class="line">D = <span class="built_in">int</span>(gmpy2.invert(E, L)) </span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">gmpy2.invert()返回值类型为&lt;class &#x27;mpz&#x27;&gt;</span></span><br><span class="line"><span class="string">invert(x,y)  计算 x 关于1模 y 的乘法逆元</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line">enstr = <span class="number">0xad939ff59f6e70bcbfad406f2494993757eee98b91bc244184a377520d06fc35</span></span><br><span class="line">destr = gmpy2.powmod(enstr, D, N)</span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">gmpy2.powmod()返回值类型为&lt;class &#x27;mpz&#x27;&gt;</span></span><br><span class="line"><span class="string">gmpy2.powmod(x,y,z)，计算x^y mod z 的值并返回</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line">flag0 = <span class="built_in">hex</span>(destr)[<span class="number">2</span>:]     <span class="comment"># flag0类型为str，存的是十六进制表示的字符串</span></span><br><span class="line">flag1 = <span class="built_in">bytes</span>.fromhex(flag0)  <span class="comment"># 将其从十六进制转换为byte类型(此时已解释成字符)</span></span><br><span class="line">flag = <span class="built_in">str</span>(flag1, <span class="string">&#x27;utf-8&#x27;</span>)  <span class="comment"># 将byte类型转换为str类型</span></span><br><span class="line"><span class="built_in">print</span>(flag)</span><br></pre></td></tr></table></figure>
<h5 id="pycrypto">pycrypto<a class="header-anchor" href="#pycrypto"> ¶ </a></h5>
<ul>
<li>
<p>安装</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo pip install pycrypto</span><br></pre></td></tr></table></figure>
</li>
<li>
<p>使用</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> gmpy</span><br><span class="line"><span class="keyword">from</span> Crypto.Util.number <span class="keyword">import</span> *</span><br><span class="line"><span class="keyword">from</span> Crypto.PublicKey <span class="keyword">import</span> RSA</span><br><span class="line"><span class="keyword">from</span> Crypto.Cipher <span class="keyword">import</span> PKCS1_v1_5</span><br><span class="line"></span><br><span class="line">msg = <span class="string">&#x27;crypto here&#x27;</span></span><br><span class="line">p = getPrime(<span class="number">128</span>)</span><br><span class="line">q = getPrime(<span class="number">128</span>)</span><br><span class="line">n = p*q</span><br><span class="line">e = getPrime(<span class="number">64</span>)</span><br><span class="line">pubkey = RSA.construct((long(n), long(e)))</span><br><span class="line">privatekey = RSA.construct((long(n), long(e), long(d), long(p), long(q)))</span><br><span class="line">key = PKCS1_v1_5.new(pubkey)</span><br><span class="line">enc = key.encrypt(msg).encode(<span class="string">&#x27;base64&#x27;</span>)</span><br><span class="line">key = PKCS1_v1_5.new(privatekey)</span><br><span class="line">msg = key.decrypt(enc.decode(<span class="string">&#x27;base64&#x27;</span>), e)</span><br></pre></td></tr></table></figure>
</li>
</ul>
<h1 id="散列算法-哈希函数">散列算法(哈希函数)<a class="header-anchor" href="#散列算法-哈希函数"> ¶ </a></h1>
<p>哈希函数（Hash Function）把消息或数据压缩成摘要，使得数据量变小。其一般模型如下图</p>
<p><img src= "" data-lazy-src="/AndroidReverse/2022/Learning_about_cryptographic_algorithms/hash.png" alt="img"></p>
<table>
<thead>
<tr>
<th style="text-align:center">算法类型</th>
<th style="text-align:center">输出 Hash 值长度</th>
<th style="text-align:center">是否有常量表</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:center">MD5</td>
<td style="text-align:center">128 bit / 256 bit</td>
<td style="text-align:center"></td>
</tr>
<tr>
<td style="text-align:center">SHA1</td>
<td style="text-align:center">160 bit</td>
<td style="text-align:center">有</td>
</tr>
<tr>
<td style="text-align:center">SHA256</td>
<td style="text-align:center">256 bit</td>
<td style="text-align:center">有</td>
</tr>
<tr>
<td style="text-align:center">SHA512</td>
<td style="text-align:center">512 bit</td>
<td style="text-align:center">有</td>
</tr>
</tbody>
</table>
<h2 id="MD5">MD5<a class="header-anchor" href="#MD5"> ¶ </a></h2>
<p>MD5 的输入输出如下</p>
<ul>
<li>输入：任意长的消息，512 比特长的分组。</li>
<li>输出：128 比特的消息摘要。</li>
</ul>
<p>此外，有时候我们获得到的 md5 是 16 位的，其实那 16 位是 32 位 md5 的长度，是从 32 位 md5 值来的。是将 32 位 md5 去掉前八位，去掉后八位得到的。</p>
<h3 id="特征">特征<a class="header-anchor" href="#特征"> ¶ </a></h3>
<p>一般来说，我们可以通过函数的初始化来判断是不是 MD5 函数。一般来说，如果一个函数有如下四个初始化的变量，可以猜测该函数为 MD5 函数，因为这是 MD5 函数的初始化 IV。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">0x67452301，0xEFCDAB89，0x98BADCFE，0x10325476</span><br></pre></td></tr></table></figure>
<h3 id="破解-2">破解<a class="header-anchor" href="#破解-2"> ¶ </a></h3>
<p>目前可以说 md5 已经基本被攻破了，一般的 MD5 的碰撞都可以在如下网上获取到</p>
<ul>
<li><a target="_blank" rel="noopener" href="http://www.cmd5.com/">http://www.cmd5.com/</a></li>
<li><a target="_blank" rel="noopener" href="http://www.ttmd5.com/">http://www.ttmd5.com/</a></li>
<li><a target="_blank" rel="noopener" href="http://pmd5.com/">http://pmd5.com/</a></li>
<li><a target="_blank" rel="noopener" href="https://www.win.tue.nl/hashclash/fastcoll_v1.0.0.5.exe.zip">https://www.win.tue.nl/hashclash/fastcoll_v1.0.0.5.exe.zip</a> (生成指定前缀的 md5 碰撞)</li>
</ul>
<h2 id="SHA1">SHA1<a class="header-anchor" href="#SHA1"> ¶ </a></h2>
<p>SHA1 的输入输出如下</p>
<ul>
<li>输入：任意长的消息，分为 <strong>512 比特</strong>长的分组。首先在消息右侧补比特 1，然后再补若干个比特 0，直到消息的比特长度满足对 512 取模后余数是 448，使其与 448 模 512 同余。</li>
<li>输出：160 比特的消息摘要。</li>
</ul>
<p>一般来说，我们可以通过函数的初始化来判断是不是 SHA1 函数。一般来说，如果一个函数有如下五个初始化的变量，可以猜测该函数为 SHA1 函数，因为这是 SHA1 函数的初始化 IV。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">0x67452301</span><br><span class="line">0xEFCDAB89</span><br><span class="line">0x98BADCFE</span><br><span class="line">0x10325476</span><br><span class="line">0xC3D2E1F0</span><br></pre></td></tr></table></figure>
<p>前面四个与 MD5 类似，后面的是新加的。</p>
<h1 id="证书格式解析">证书格式解析<a class="header-anchor" href="#证书格式解析"> ¶ </a></h1>
<h2 id="PEM格式证书">PEM格式证书<a class="header-anchor" href="#PEM格式证书"> ¶ </a></h2>
<p>PEM 以 <code>-----BEGIN</code> 开头，以 <code>-----END</code> 结尾，中间包含 ASN.1 格式的数据。ASN.1 是经过 base64 转码的二进制数据。</p>
<h3 id="对RSA的pem证书格式解析">对RSA的pem证书格式解析<a class="header-anchor" href="#对RSA的pem证书格式解析"> ¶ </a></h3>
<p>RSA PEM格式通常为如下两种</p>
<p>PKCS#1格式</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">-----BEGIN RSA PRIVATE KEY-----</span><br><span class="line">YG6XRKfkcxnaXGfFDWHL....</span><br><span class="line">-----END PRIVATE KEY-----</span><br></pre></td></tr></table></figure>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">-----BEGIN RSA PUBLIC KEY-----</span><br><span class="line">YG6XRKfkcxnaXGfFDWHL....</span><br><span class="line">-----END RSA PUBLIC KEY-----</span><br></pre></td></tr></table></figure>
<p>PKCS#8格式</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">-----BEGIN PRIVATE KEY-----</span><br><span class="line">YG6XRKfkcxnaXGfFDWHL....</span><br><span class="line">-----END PRIVATE KEY-----</span><br></pre></td></tr></table></figure>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">-----BEGIN PUBLIC KEY-----</span><br><span class="line">YG6XRKfkcxnaXGfFDWHL....</span><br><span class="line">-----END PRIVATE KEY-----</span><br></pre></td></tr></table></figure>
<p>带有PUBLIC的是RSA的公钥，带有PRIVATE的是RSA的私钥。</p>
<p>PKCS#1格式的密钥头部带有RSA，专指RSA的密钥。</p>
<p>PKCS#8格式的密钥则有可能不是RSA的秘钥，而密钥类型在中间的数据中。</p>
<p>中间的数据是Base64格式的。Base64解码后的二进制数据是<code>.der</code>格式证书的内容。<strong>实际上，PEM就是把DER格式的数据用base64编码后，然后再在头尾加上一段“-----”开始的标记而已。</strong></p>
<p>而<code>DER</code>格式是二进制形式，并遵守<a target="_blank" rel="noopener" href="https://zh.wikipedia.org/wiki/ASN.1">ASN.1</a>二进制编码格式。<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup></p>
<h4 id="PKCS-1格式pem解析">PKCS#1格式pem解析<a class="header-anchor" href="#PKCS-1格式pem解析"> ¶ </a></h4>
<h5 id="私钥">私钥<a class="header-anchor" href="#私钥"> ¶ </a></h5>
<p>首先先利用<a target="_blank" rel="noopener" href="https://github.com/ius/rsatool">ius/rsatool: rsatool can be used to calculate RSA and RSA-CRT parameters (github.com)</a>工具生成一个PKCS#1格式的私钥</p>
<p>克隆仓库</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">git <span class="built_in">clone</span> https://github.com/ius/rsatool.git</span><br><span class="line"><span class="built_in">cd</span> rsatool</span><br></pre></td></tr></table></figure>
<p>使用前需安装依赖</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">python -m pip install gmpy2</span><br><span class="line">python -m pip install pyasn1</span><br></pre></td></tr></table></figure>
<p>使用命令如下(相应的p、q、e值参考上述例子)</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">λ python rsatool.py -f PEM -o private1.pem -p 61 -q 53 -e 17</span><br><span class="line">Using (p, q) to calculate RSA paramaters</span><br><span class="line"></span><br><span class="line">n = 3233 (0xca1)</span><br><span class="line"></span><br><span class="line">e = 17 (0x11)</span><br><span class="line"></span><br><span class="line">d = 2753 (0xac1)</span><br><span class="line"></span><br><span class="line">p = 61 (0x3d)</span><br><span class="line"></span><br><span class="line">q = 53 (0x35)</span><br><span class="line"></span><br><span class="line">Saving PEM as private1.pem</span><br></pre></td></tr></table></figure>
<p>这样就在当前目录生成了格式为PKCS#1的RSA私钥文件<code>private1.pem</code>（Base64每76个字符换一行）</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">-----BEGIN RSA PRIVATE KEY-----</span><br><span class="line">MB0CAQACAgyhAgERAgIKwQIBPQIBNQIBNQIBMQIBJg==</span><br><span class="line">-----END RSA PRIVATE KEY-----</span><br></pre></td></tr></table></figure>
<p>base64解码后得到二进制数据如下：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">30 1d 02 01 00 02 02 0c a1 02 01 11 02 02 0a c1 02 01 3d 02 01 35 02 01 35 02 01 31 02 01 26</span><br></pre></td></tr></table></figure>
<p>标准的ASN.1编码规则有<a target="_blank" rel="noopener" href="https://zh.wikipedia.org/w/index.php?title=BER&amp;action=edit&amp;redlink=1">基本编码规则</a>（BER，Basic Encoding Rules）、<a target="_blank" rel="noopener" href="https://zh.wikipedia.org/w/index.php?title=DER&amp;action=edit&amp;redlink=1">唯一编码规则</a>（DER，Distinguished Encoding Rules）等编码规则。而该格式采用的是DER编码，DER编码格式举例详见：<a target="_blank" rel="noopener" href="https://zh.wikipedia.org/wiki/ASN.1#DER%E7%9A%84%E7%B7%A8%E7%A2%BC%E7%AF%84%E4%BE%8B">DER编码范例</a></p>
<p>所以上述解码的字符串也可以解释了</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">30</span> <span class="number">1</span>d           <span class="comment">// RSAPrivateKey, len=0x1d</span></span><br><span class="line">  <span class="number">02</span> <span class="number">01</span> <span class="number">00</span>      <span class="comment">// version</span></span><br><span class="line">  <span class="number">02</span> <span class="number">02</span> <span class="number">0</span>c a1   <span class="comment">// modulus</span></span><br><span class="line">  <span class="number">02</span> <span class="number">01</span> <span class="number">11</span>      <span class="comment">// publicExponent</span></span><br><span class="line">  <span class="number">02</span> <span class="number">02</span> <span class="number">0</span>a c1   <span class="comment">// privateExponent</span></span><br><span class="line">  <span class="number">02</span> <span class="number">01</span> <span class="number">3</span>d      <span class="comment">// prime1</span></span><br><span class="line">  <span class="number">02</span> <span class="number">01</span> <span class="number">35</span>      <span class="comment">// prime2</span></span><br><span class="line">  <span class="number">02</span> <span class="number">01</span> <span class="number">35</span>      <span class="comment">// exponent1</span></span><br><span class="line">  <span class="number">02</span> <span class="number">01</span> <span class="number">31</span>      <span class="comment">// exponent2</span></span><br><span class="line">  <span class="number">02</span> <span class="number">01</span> <span class="number">26</span>      <span class="comment">// coefficient</span></span><br></pre></td></tr></table></figure>
<p><strong>注意：此处的字节序为大端序</strong></p>
<p>至于内容的格式，可以参考在<a target="_blank" rel="noopener" href="https://datatracker.ietf.org/doc/html/rfc2437#section-11.1.2">RFC 2347 RSA私钥ASN.1定义</a></p>
<blockquote>
<p>An RSA private key should be represented with ASN.1 type<br>
RSAPrivateKey:</p>
  <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">RSAPrivateKey ::= SEQUENCE &#123;</span><br><span class="line">version Version,</span><br><span class="line">modulus INTEGER, -- n</span><br><span class="line">publicExponent INTEGER, -- e</span><br><span class="line">privateExponent INTEGER, -- d</span><br><span class="line">prime1 INTEGER, -- p</span><br><span class="line">prime2 INTEGER, -- q</span><br><span class="line">exponent1 INTEGER, -- d mod (p-1)</span><br><span class="line">exponent2 INTEGER, -- d mod (q-1)</span><br><span class="line">coefficient INTEGER -- (inverse of q) mod p &#125;</span><br><span class="line"></span><br><span class="line">Version ::= INTEGER</span><br></pre></td></tr></table></figure>
<p>The fields of type RSAPrivateKey have the following meanings:</p>
<p>-version is the version number, for compatibility with future<br>
revisions of this document. It shall be 0 for this version of the<br>
document.<br>
-modulus is the modulus n.<br>
-publicExponent is the public exponent e.<br>
-privateExponent is the private exponent d.<br>
-prime1 is the prime factor p of n.<br>
-prime2 is the prime factor q of n.<br>
-exponent1 is d mod (p-1).<br>
-exponent2 is d mod (q-1).<br>
-coefficient is the Chinese Remainder Theorem coefficient q-1 mod p.</p>
</blockquote>
<p>也就正如<code>openssl</code>命令解析的一致了</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">openssl rsa -<span class="keyword">in</span> private1.pem -text -out private1.txt</span><br></pre></td></tr></table></figure>
<p>内容如下</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">RSA Private-Key: (12 bit, 2 primes)</span><br><span class="line">modulus: 3233 (0xca1)</span><br><span class="line">publicExponent: 17 (0x11)</span><br><span class="line">privateExponent: 2753 (0xac1)</span><br><span class="line">prime1: 61 (0x3d)</span><br><span class="line">prime2: 53 (0x35)</span><br><span class="line">exponent1: 53 (0x35)</span><br><span class="line">exponent2: 49 (0x31)</span><br><span class="line">coefficient: 38 (0x26)</span><br><span class="line">-----BEGIN RSA PRIVATE KEY-----</span><br><span class="line">MB0CAQACAgyhAgERAgIKwQIBPQIBNQIBNQIBMQIBJg==</span><br><span class="line">-----END RSA PRIVATE KEY-----</span><br></pre></td></tr></table></figure>
<h5 id="公钥">公钥<a class="header-anchor" href="#公钥"> ¶ </a></h5>
<p>根据上述私钥，生成公钥</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">openssl rsa -<span class="keyword">in</span> private1.pem -out public1.pem -RSAPublicKey_out</span><br></pre></td></tr></table></figure>
<p>得到公钥文件<code>public1.pem</code></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">-----BEGIN RSA PUBLIC KEY-----</span><br><span class="line">MAcCAgyhAgER</span><br><span class="line">-----END RSA PUBLIC KEY-----</span><br></pre></td></tr></table></figure>
<p>Base解码后得到如下，同样是采用<a target="_blank" rel="noopener" href="https://zh.wikipedia.org/wiki/ASN.1#DER%E7%9A%84%E7%B7%A8%E7%A2%BC%E7%AF%84%E4%BE%8B">DER编码</a></p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">30</span> <span class="number">07</span>           <span class="comment">// PublicKey,len=7</span></span><br><span class="line">  <span class="number">02</span> <span class="number">02</span> <span class="number">0</span>c a1   <span class="comment">// modulus</span></span><br><span class="line">  <span class="number">02</span> <span class="number">01</span> <span class="number">11</span>      <span class="comment">// publicExponent</span></span><br></pre></td></tr></table></figure>
<p>该格式参考的<a target="_blank" rel="noopener" href="https://datatracker.ietf.org/doc/html/rfc2437#section-11.1.1">RFC 2347 RSA公钥ASN.1定义</a></p>
<blockquote>
<p>An RSA public key should be represented with the ASN.1 type<br>
RSAPublicKey:</p>
  <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">RSAPublicKey::=SEQUENCE&#123;</span><br><span class="line"> modulus INTEGER, -- n</span><br><span class="line"> publicExponent INTEGER -- e &#125;</span><br></pre></td></tr></table></figure>
<p>(This type is specified in X.509 and is retained here for<br>
compatibility.)</p>
<p>The fields of type RSAPublicKey have the following meanings:<br>
-modulus is the modulus n.<br>
-publicExponent is the public exponent e.</p>
</blockquote>
<p>相较于私钥，公钥部分较为简单，仅有<code>Modulus(N)</code>和<code>Exponent(e)</code>。</p>
<p>于是我们可以解析出相应的信息如下</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Modulus: 0xca1</span><br><span class="line">Exponent: 0x11</span><br></pre></td></tr></table></figure>
<h4 id="PKCS-8格式pem解析">PKCS#8格式pem解析<a class="header-anchor" href="#PKCS-8格式pem解析"> ¶ </a></h4>
<h5 id="私钥-2">私钥<a class="header-anchor" href="#私钥-2"> ¶ </a></h5>
<p>首先先将上述PKCS#1格式私钥转换为PKCS#8格式</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">openssl pkcs8 -topk8 -inform PEM -<span class="keyword">in</span> private1.pem -outform pem -nocrypt -out private8.pem</span><br></pre></td></tr></table></figure>
<p>可以得到如下（Base64每64个字符换一行）</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">-----BEGIN PRIVATE KEY-----</span><br><span class="line">MDMCAQAwDQYJKoZIhvcNAQEBBQAEHzAdAgEAAgIMoQIBEQICCsECAT0CATUCATUC</span><br><span class="line">ATECASY=</span><br><span class="line">-----END PRIVATE KEY-----</span><br></pre></td></tr></table></figure>
<p>参考<a target="_blank" rel="noopener" href="https://datatracker.ietf.org/doc/html/rfc5208#appendix-A">RFC 5208 - Public-Key Cryptography Standards (PKCS) #8: Private-Key Information Syntax Specification Version 1.2 (ietf.org)</a></p>
<blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">&gt;PrivateKeyInfo ::= SEQUENCE &#123;</span><br><span class="line">&gt;version Version,</span><br><span class="line">&gt;privateKeyAlgorithm AlgorithmIdentifier &#123;&#123;PrivateKeyAlgorithms&#125;&#125;,</span><br><span class="line">&gt;privateKey PrivateKey,</span><br><span class="line">&gt;attributes [0] Attributes OPTIONAL &#125;</span><br><span class="line"></span><br><span class="line">&gt;Version ::= INTEGER &#123;v1(0)&#125; (v1,...)</span><br><span class="line"></span><br><span class="line">&gt;PrivateKey ::= OCTET STRING</span><br><span class="line"></span><br><span class="line">&gt;Attributes ::= SET OF Attribute</span><br></pre></td></tr></table></figure>
<p>（同时包含Encrypted private-key information syntax）</p>
</blockquote>
<p>可以解析二进制数据位为如下</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">30</span> <span class="number">33</span></span><br><span class="line">  <span class="number">02</span> <span class="number">01</span> <span class="number">00</span>      <span class="comment">// Version - 0 (v1998)</span></span><br><span class="line">  <span class="number">30</span> <span class="number">0</span>d         <span class="comment">// AlgorithmIdentifier, len=14</span></span><br><span class="line">    <span class="number">06</span> <span class="number">09</span> <span class="number">2</span>a <span class="number">86</span> <span class="number">48</span> <span class="number">86</span> f7 <span class="number">0</span>d <span class="number">01</span> <span class="number">01</span> <span class="number">01</span>    <span class="comment">// 对于RSA该值固定为1.2.840.113549.1.1.1</span></span><br><span class="line">    <span class="number">05</span> <span class="number">00</span>       <span class="comment">// NULL(可选参数)</span></span><br><span class="line">  <span class="number">04</span> <span class="number">1f</span>             <span class="comment">// PrivateKey, len=0x1f</span></span><br><span class="line">    <span class="number">30</span> <span class="number">1</span>d           <span class="comment">// RSAPrivateKey, len=0x1d</span></span><br><span class="line">      <span class="number">02</span> <span class="number">01</span> <span class="number">00</span>      <span class="comment">// version</span></span><br><span class="line">      <span class="number">02</span> <span class="number">02</span> <span class="number">0</span>c a1   <span class="comment">// modulus</span></span><br><span class="line">      <span class="number">02</span> <span class="number">01</span> <span class="number">11</span>      <span class="comment">// publicExponent</span></span><br><span class="line">      <span class="number">02</span> <span class="number">02</span> <span class="number">0</span>a c1   <span class="comment">// privateExponent</span></span><br><span class="line">      <span class="number">02</span> <span class="number">01</span> <span class="number">3</span>d      <span class="comment">// prime1</span></span><br><span class="line">      <span class="number">02</span> <span class="number">01</span> <span class="number">35</span>      <span class="comment">// prime2</span></span><br><span class="line">      <span class="number">02</span> <span class="number">01</span> <span class="number">35</span>      <span class="comment">// exponent1</span></span><br><span class="line">      <span class="number">02</span> <span class="number">01</span> <span class="number">31</span>      <span class="comment">// exponent2</span></span><br><span class="line">      <span class="number">02</span> <span class="number">01</span> <span class="number">26</span>      <span class="comment">// coefficient</span></span><br></pre></td></tr></table></figure>
<p>attributes为可选节，这里并没有</p>
<p>同时可以看到RSAPrivateKey部分就是PKCS#1格式中的数据，PKCS#8仅仅是多了些头部描述，因此PKCS#8可以通过不同的AlgorithmIdentifier值(RSA为<code>1.2.840.113549.1.1.1</code>)更加通用的表示其他算法</p>
<h5 id="公钥-2">公钥<a class="header-anchor" href="#公钥-2"> ¶ </a></h5>
<p>通过<code>openssl</code>生成PKCS#8格式的公钥</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">openssl rsa -<span class="keyword">in</span> private1.pem -pubout -out public8.pem</span><br></pre></td></tr></table></figure>
<p>得到</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">-----BEGIN PUBLIC KEY-----</span><br><span class="line">MBswDQYJKoZIhvcNAQEBBQADCgAwBwICDKECARE=</span><br><span class="line">-----END PUBLIC KEY-----</span><br></pre></td></tr></table></figure>
<p>转换格式后</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">30</span> <span class="number">1b</span></span><br><span class="line">  <span class="number">30</span> <span class="number">0</span>d             <span class="comment">// AlgorithmIdentifier, len=14</span></span><br><span class="line">    <span class="number">06</span> <span class="number">09</span> <span class="number">2</span>a <span class="number">86</span> <span class="number">48</span> <span class="number">86</span> f7 <span class="number">0</span>d <span class="number">01</span> <span class="number">01</span> <span class="number">01</span>  <span class="comment">// RSA该值固定为1.2.840.113549.1.1.1</span></span><br><span class="line">    <span class="number">05</span> <span class="number">00</span>           <span class="comment">// NULL(可选参数)</span></span><br><span class="line">  <span class="number">03</span> <span class="number">0</span>a             <span class="comment">// PublicKey</span></span><br><span class="line">    <span class="number">00</span>              <span class="comment">// 不知</span></span><br><span class="line">    <span class="number">30</span> <span class="number">07</span>           <span class="comment">// PublicKey,len=7</span></span><br><span class="line">      <span class="number">02</span> <span class="number">02</span> <span class="number">0</span>c a1   <span class="comment">// modulus</span></span><br><span class="line">      <span class="number">02</span> <span class="number">01</span> <span class="number">11</span>      <span class="comment">// publicExponent</span></span><br></pre></td></tr></table></figure>
<blockquote>
<p>格式：摘自<a target="_blank" rel="noopener" href="https://www.codeproject.com/Articles/25487/Cryptographic-Interoperability-Keys">Cryptographic Interoperability: Keys - CodeProject</a></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">&gt;PublicKeyInfo ::= SEQUENCE &#123;</span><br><span class="line">&gt;algorithm AlgorithmIdentifier,</span><br><span class="line">&gt;PublicKey BIT STRING &#125;</span><br><span class="line"></span><br><span class="line">&gt;AlgorithmIdentifier ::= SEQUENCE &#123;</span><br><span class="line">&gt;algorithm ALGORITHM.id,</span><br><span class="line">&gt;parameters ALGORITHM.type OPTIONAL &#125;</span><br></pre></td></tr></table></figure>
</blockquote>
<h4 id="openssl-相关命令">openssl 相关命令<a class="header-anchor" href="#openssl-相关命令"> ¶ </a></h4>
<p><strong>rsa命令中</strong></p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">λ openssl rsa -<span class="built_in">help</span></span><br><span class="line">Usage: rsa [options]</span><br><span class="line">Valid options are:</span><br><span class="line"> -<span class="built_in">help</span>              Display this summary</span><br><span class="line"> -inform format     Input format, one of DER PEM</span><br><span class="line"> -outform format    Output format, one of DER PEM PVK</span><br><span class="line"> -<span class="keyword">in</span> val            Input file</span><br><span class="line"> -out outfile       Output file</span><br><span class="line"> -pubin             Expect a public key <span class="keyword">in</span> input file</span><br><span class="line"> -pubout            Output a public key</span><br><span class="line"> -passout val       Output file pass phrase <span class="built_in">source</span></span><br><span class="line"> -passin val        Input file pass phrase <span class="built_in">source</span></span><br><span class="line"> -RSAPublicKey_in   Input is an RSAPublicKey</span><br><span class="line"> -RSAPublicKey_out  Output is an RSAPublicKey</span><br><span class="line"> -noout             Don<span class="string">&#x27;t print key out</span></span><br><span class="line"><span class="string"> -text              Print the key in text</span></span><br><span class="line"><span class="string"> -modulus           Print the RSA key modulus</span></span><br><span class="line"><span class="string"> -check             Verify key consistency</span></span><br><span class="line"><span class="string"> -*                 Any supported cipher</span></span><br><span class="line"><span class="string"> -pvk-strong        Enable &#x27;</span>Strong<span class="string">&#x27; PVK encoding level (default)</span></span><br><span class="line"><span class="string"> -pvk-weak          Enable &#x27;</span>Weak<span class="string">&#x27; PVK encoding level</span></span><br><span class="line"><span class="string"> -pvk-none          Don&#x27;</span>t enforce PVK encoding</span><br><span class="line"> -engine val        Use engine, possibly a hardware device</span><br></pre></td></tr></table></figure>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">openssl rsa -<span class="keyword">in</span> private1.pem -out public1.pem -RSAPublicKey_out     <span class="comment"># 从PKCS#1格式私钥 导出 PKCS#1格式公钥</span></span><br><span class="line">openssl rsa -<span class="keyword">in</span> private1.pem -pubout -out public8.pem               <span class="comment"># 从PKCS#1格式私钥 导出 PKCS#8格式公钥</span></span><br><span class="line"></span><br><span class="line">openssl rsa -<span class="keyword">in</span> private8.pem -out private1.pem						<span class="comment"># 将PKCS#8格式私钥 转换为 PKCS#1格式私钥</span></span><br><span class="line">openssl pkcs8 -topk8 -inform PEM -<span class="keyword">in</span> private1.pem -outform pem -nocrypt -out private8.pem       <span class="comment"># 将PKCS#1格式私钥 转换为 PKCS#8格式私钥</span></span><br><span class="line"></span><br><span class="line">openssl rsa -RSAPublicKey_in -<span class="keyword">in</span> public1.pem -pubout -out public8.pem	<span class="comment"># 将PKCS#1格式公钥 转换为 PKCS#8格式公钥</span></span><br><span class="line">openssl rsa -pubin -<span class="keyword">in</span> public8.pem -RSAPublicKey_out -out public1.pem	<span class="comment"># 将PKCS#8格式公钥 转换为 PKCS#1格式公钥</span></span><br></pre></td></tr></table></figure>
<p>可以看出</p>
<ul>
<li><code>-RSAPublicKey_in</code> 是输入PKCS#1的公钥</li>
<li><code>-RSAPublicKey_out</code> 是输出PKCS#1的公钥</li>
<li><code>-pubin</code> 是输入PKCS#8的公钥</li>
<li><code>-pubout</code> 是输出PKCS#8的公钥</li>
</ul>
<h3 id="其他">其他<a class="header-anchor" href="#其他"> ¶ </a></h3>
<p>继续请参考</p>
<ul>
<li><a target="_blank" rel="noopener" href="https://www.codeproject.com/Articles/25487/Cryptographic-Interoperability-Keys">Cryptographic Interoperability: Keys - CodeProject</a></li>
<li><a target="_blank" rel="noopener" href="https://cloud.tencent.com/developer/article/1424668">X.509、PKCS文件格式介绍 - 云+社区 - 腾讯云 (tencent.com)</a></li>
<li><a target="_blank" rel="noopener" href="https://zhuanlan.zhihu.com/p/345324498">深入剖析 RSA 密钥原理及实践 - 知乎 (zhihu.com)</a></li>
<li><a target="_blank" rel="noopener" href="https://www.cnblogs.com/littleatp/p/7384706.html">公钥证书编码解读 - 美码师 - 博客园 (cnblogs.com)</a></li>
<li><a target="_blank" rel="noopener" href="https://qastack.cn/server/9708/what-is-a-pem-file-and-how-does-it-differ-from-other-openssl-generated-key-file">什么是Pem文件，它与其他OpenSSL生成的密钥文件格式有何区别？ (qastack.cn)</a></li>
<li><a target="_blank" rel="noopener" href="https://blog.freessl.cn/ssl-cert-format-introduce/">SSL 证书格式普及，PEM、CER、JKS、PKCS12 (freessl.cn)</a></li>
</ul>
<h1 id="JAVA实现加解密">JAVA实现加解密<a class="header-anchor" href="#JAVA实现加解密"> ¶ </a></h1>
<h2 id="Java加解密环境配置">Java加解密环境配置<a class="header-anchor" href="#Java加解密环境配置"> ¶ </a></h2>
<p><a target="_blank" rel="noopener" href="https://www.docin.com/p-1475296172.html"><strong>SunJCE Provider 支持的Cipher详细信息(部分)</strong> — 关于加密数据的填充方式的研究 - 豆丁网 (docin.com)</a></p>
<table>
<thead>
<tr>
<th>algorithm(算法)</th>
<th>mode(工作模式)</th>
<th>padding(填充模式)</th>
</tr>
</thead>
<tbody>
<tr>
<td>AES</td>
<td>ECB、CBC、PCBC、CTR、CTS、CFB、CFBB-CFB128等</td>
<td>NoPadding、PKCS5Padding、ISO10126Padding</td>
</tr>
<tr>
<td>AESWrap</td>
<td>ECB</td>
<td>NoPadding</td>
</tr>
<tr>
<td>ARCFOUR</td>
<td>ECB</td>
<td>NoPadding</td>
</tr>
<tr>
<td>Blowfish、DES、DESede、RC2</td>
<td>ECB、CBC、PCBC、CTR、CTS、CFB、CFBB-CFB128等</td>
<td>NoPadding、PKCS5Padding、ISO10126Padding</td>
</tr>
<tr>
<td>DESedeWrap</td>
<td>CBC</td>
<td>NoPadding</td>
</tr>
<tr>
<td>PBEWithMD5AndDES、PBEWithMD5AndTripleDES、PBEWithSHA1AndDESede、BEWithSHA1AndRC2_40</td>
<td>CBC</td>
<td>PKCS5Padding</td>
</tr>
<tr>
<td>RSA</td>
<td>ECB、NONE</td>
<td>NoPadding、PKCS1Padding等</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th style="text-align:center">SunJCE 支持</th>
<th style="text-align:center">需添加 BouncyCastle 支持</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:center">NoPadding</td>
<td style="text-align:center"></td>
</tr>
<tr>
<td style="text-align:center">PKCS5Padding</td>
<td style="text-align:center">PKCS7Padding</td>
</tr>
<tr>
<td style="text-align:center">ANSI X923Padding</td>
<td style="text-align:center"></td>
</tr>
<tr>
<td style="text-align:center">ISO10126Padding</td>
<td style="text-align:center"></td>
</tr>
<tr>
<td style="text-align:center">ISO7816-4Padding</td>
<td style="text-align:center"></td>
</tr>
<tr>
<td style="text-align:center">ZeroBytePadding</td>
<td style="text-align:center"></td>
</tr>
<tr>
<td style="text-align:center">TBCPadding</td>
<td style="text-align:center"></td>
</tr>
<tr>
<td style="text-align:center"></td>
<td style="text-align:center">PKCS1Padding</td>
</tr>
</tbody>
</table>
<h3 id="1-解除java-jdk政策限制">1. 解除java jdk政策限制<a class="header-anchor" href="#1-解除java-jdk政策限制"> ¶ </a></h3>
<ul>
<li>
<p>对于Java 8 Update 144和更早版本，需要安装Java密码学扩展（JCE）无限强度管辖权策略文件。</p>
<ul>
<li>
<p>相关解除政策限制文件下载 <a target="_blank" rel="noopener" href="http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html">jdk6</a> | <a target="_blank" rel="noopener" href="http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html">jdk7</a> | <a target="_blank" rel="noopener" href="http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html">jdk8</a></p>
</li>
<li>
<p>解压缩后将下载文件中的两个jar替换在<code>%JAVA_HOME%\jre\lib\security</code>下的jar</p>
</li>
<li>
<blockquote>
<p>注意：如果您以后决定恢复到原始的受限策略版本，请首先在中备份原始JCE策略文件（US_export_policy.jar和local_policy.jar）<code>$JAVA_HOME/jre/lib/security</code>。</p>
</blockquote>
</li>
</ul>
</li>
<li>
<p>Java 8 Update 151及更高版本</p>
<ul>
<li>
<p>包括了“无限强度管辖策略”，但默认情况下不使用。要启用它，您需要<code>java.security</code>在<code>$JAVA_HOME/jre/lib/security</code>（对于JDK）或<code>$JAVA_HOME/lib/security</code>（对于JRE）中编辑<code>java.security</code>文件。取消注释（或包括）该行：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">crypto.policy=unlimited</span><br></pre></td></tr></table></figure>
</li>
</ul>
</li>
<li>
<p>jdk11</p>
<blockquote>
<p>The default JCE policy files bundled in this Java Runtime Environment allow for “unlimited” cryptographic strengths.</p>
<p>For convenience, this software also contains the historic “limited” strength policy files which restricts cryptographic strengths. To use the limited strength policy, instead of the default unlimited policy, you must update the “crypto.policy” Security property (in <code>/conf/security/java.security</code>) to point to the appropriate directory.</p>
<p>You are advised to consult your export/import control counsel or attorney to determine the exact requirements of your location, and what policy settings should be used.</p>
</blockquote>
<p>大致意思就是<strong>JDK11默认是无限制</strong>，可以在<code>$JAVA_HOME/conf/security/java.security</code>文件中配置<code>crypto.policy</code>属性为<code>unlimited</code>或者<code>limited</code></p>
</li>
</ul>
<p>真tm乱</p>
<h4 id="检测是否已经解除限制">检测是否已经解除限制<a class="header-anchor" href="#检测是否已经解除限制"> ¶ </a></h4>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">try</span> &#123;</span><br><span class="line">        KeyGenerator kg =  KeyGenerator.getInstance(<span class="string">&quot;AES&quot;</span>);</span><br><span class="line">        kg.init(<span class="number">256</span>);</span><br><span class="line">        SecretKey secretKey=kg.generateKey();</span><br><span class="line">        System.out.println(secretKey.getFormat());</span><br><span class="line">    &#125; <span class="keyword">catch</span> (NoSuchAlgorithmException e) &#123;</span><br><span class="line">        e.printStackTrace();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>运行成功则已经解除限制</p>
<h3 id="2-配置BouncyCastle">2.配置BouncyCastle<a class="header-anchor" href="#2-配置BouncyCastle"> ¶ </a></h3>
<p>下载BC：<a target="_blank" rel="noopener" href="https://www.bouncycastle.org/latest_releases.html">BouncyCastle下载地址</a></p>
<h4 id="（方法一）全局静态配置">（方法一）全局静态配置<a class="header-anchor" href="#（方法一）全局静态配置"> ¶ </a></h4>
<p>把<code>bcprov-ext*.jar</code>文件复制到 <code>%JAVA_HOME%\jre\lib\ext</code> 目录下面<br>
修改配置文件<code>\jre\lib\security\java.security</code></p>
<figure class="highlight cmd"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">security.provider.<span class="number">1</span>=sun.security.provider.Sun</span><br><span class="line">security.provider.<span class="number">2</span>=sun.security.rsa.SunRsaSign</span><br><span class="line">security.provider.<span class="number">3</span>=sun.security.ec.SunEC</span><br><span class="line">security.provider.<span class="number">4</span>=com.sun.<span class="built_in">net</span>.ssl.internal.ssl.Provider</span><br><span class="line">security.provider.<span class="number">5</span>=com.sun.crypto.provider.SunJCE</span><br><span class="line">security.provider.<span class="number">6</span>=sun.security.jgss.SunProvider</span><br><span class="line">security.provider.<span class="number">7</span>=com.sun.security.sasl.Provider</span><br><span class="line">security.provider.<span class="number">8</span>=org.jcp.xml.dsig.internal.dom.XMLDSigRI</span><br><span class="line">security.provider.<span class="number">9</span>=sun.security.smartcardio.SunPCSC</span><br><span class="line">security.provider.<span class="number">10</span>=sun.security.mscapi.SunMSCAPI</span><br><span class="line">...</span><br><span class="line"></span><br><span class="line">security.provider.<span class="number">11</span>=org.bouncycastle.jce.provider.BouncyCastleProvider</span><br></pre></td></tr></table></figure>
<p>这样添加后便可以启用了，如果IDEA找不到类(无提示)，去【Project Structure】-&gt;【Platform Settings】-&gt; 【SDKs】添加相应的jar包路径，或者直接删掉jdk再重新添加。</p>
<h4 id="（方法二）动态添加jar">（方法二）动态添加jar<a class="header-anchor" href="#（方法二）动态添加jar"> ¶ </a></h4>
<p>导入不含ext的另一个jar</p>
<p>所使用的类中添加</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">static</span> &#123;</span><br><span class="line">    Security.addProvider(<span class="keyword">new</span> BouncyCastleProvider());</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h4 id="验证使用">验证使用<a class="header-anchor" href="#验证使用"> ¶ </a></h4>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">    Provider provider = Security.getProvider(<span class="string">&quot;BC&quot;</span>);</span><br><span class="line">    System.out.println(provider);</span><br><span class="line">    <span class="keyword">for</span>(Map.Entry&lt;Object,Object&gt; entry:provider.entrySet())&#123;</span><br><span class="line">        System.out.println(entry.getKey()+<span class="string">&quot; --&gt; &quot;</span>+entry.getValue());</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>运行类似下，则配置成功</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">BC version 1.69</span><br><span class="line">Cipher.ARIARFC3211WRAP --&gt; org.bouncycastle.jcajce.provider.symmetric.ARIA<span class="variable">$RFC3211Wrap</span></span><br><span class="line">Alg.Alias.Cipher.1.3.6.1.4.1.22554.1.1.2.1.22 --&gt; PBEWITHSHAAND192BITAES-CBC-BC</span><br><span class="line">Alg.Alias.AlgorithmParameters.SHA512withRSA/PSS --&gt; PSS</span><br><span class="line">Alg.Alias.Mac.HMAC/Skein-256-224 --&gt; HMACSkein-256-224</span><br><span class="line">Alg.Alias.MessageDigest.SHA256 --&gt; SHA-256</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h3 id="配置CommonsCodec">配置CommonsCodec<a class="header-anchor" href="#配置CommonsCodec"> ¶ </a></h3>
<p><a target="_blank" rel="noopener" href="https://commons.apache.org/proper/commons-codec/download_codec.cgi">Commons Codec下载地址</a></p>
<h1 id="JavaScript实现加解密">JavaScript实现加解密<a class="header-anchor" href="#JavaScript实现加解密"> ¶ </a></h1>
<h2 id="CryptoJS库使用">CryptoJS库使用<a class="header-anchor" href="#CryptoJS库使用"> ¶ </a></h2>
<p>下载地址：</p>
<ul>
<li>GitHub地址：<a target="_blank" rel="noopener" href="https://github.com/brix/crypto-js">https://github.com/brix/crypto-js</a></li>
<li>npm下载：<code>npm install crypto-js</code></li>
</ul>
<p>使用其中的<code>crypto-js.js</code>文件</p>
<p><strong>更多使用示例参照<a target="_blank" rel="noopener" href="https://cryptojs.gitbook.io/docs">CryptoJS - CryptoJS (gitbook.io)</a></strong></p>
<h3 id="解析数据">解析数据<a class="header-anchor" href="#解析数据"> ¶ </a></h3>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 转为字节数组</span></span><br><span class="line"><span class="keyword">var</span> wordArray = CryptoJS.enc.Utf8.parse(utf8String);</span><br><span class="line"><span class="keyword">var</span> wordArray = CryptoJS.enc.Hex.parse(hexString);</span><br><span class="line"><span class="keyword">var</span> wordArray = CryptoJS.enc.Base64.parse(base64String);</span><br><span class="line"><span class="keyword">var</span> wordArray = CryptoJS.enc.Latin1.parse(latin1String);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 字节数组转</span></span><br><span class="line"><span class="keyword">var</span> utf8String = CryptoJS.enc.Utf8.stringify(wordArray);</span><br><span class="line"><span class="keyword">var</span> hexString = CryptoJS.enc.Hex.stringify(wordArray);</span><br><span class="line"><span class="keyword">var</span> base64String = CryptoJS.enc.Base64.stringify(wordArray);</span><br><span class="line"><span class="keyword">var</span> latin1String = CryptoJS.enc.Latin1.stringify(wordArray);</span><br><span class="line"></span><br><span class="line">CryptoJS.format.OpenSSL.parse(sslString);</span><br><span class="line">CryptoJS.format.OpenSSL.stringify(wordArray);</span><br></pre></td></tr></table></figure>
<h3 id="MD">MD<a class="header-anchor" href="#MD"> ¶ </a></h3>
<h4 id="MD5-2">MD5<a class="header-anchor" href="#MD5-2"> ¶ </a></h4>
<h5 id="简单调用">简单调用<a class="header-anchor" href="#简单调用"> ¶ </a></h5>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> hash = CryptoJS.MD5(message);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> hash = CryptoJS.MD5(wordArray);</span><br><span class="line"><span class="comment">// MAC</span></span><br><span class="line"><span class="keyword">var</span> hmac = CryptoJS.HmacMD5(message, key);</span><br></pre></td></tr></table></figure>
<h5 id="复杂调用">复杂调用<a class="header-anchor" href="#复杂调用"> ¶ </a></h5>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">md5Example</span>(<span class="params">data</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> hasher = CryptoJS.algo.MD5.create();</span><br><span class="line">    hasher.reset(); <span class="comment">// 清掉之前设置的明文数据</span></span><br><span class="line">    hasher.update(data);    <span class="comment">// 添加明文数据</span></span><br><span class="line">    <span class="keyword">var</span> hash = hasher.finalize();   <span class="comment">// 进行加密</span></span><br><span class="line">    <span class="keyword">return</span> hash;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>HmacMD5</strong></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">hmacmd5Example</span>(<span class="params">data, key</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> hmacHasher = CryptoJS.algo.HMAC.create(CryptoJS.algo.MD5, key);</span><br><span class="line">    hmacHasher.reset(); <span class="comment">// 清掉之前设置的明文数据</span></span><br><span class="line">    hmacHasher.update(data); <span class="comment">// 添加明文数据</span></span><br><span class="line">    <span class="keyword">var</span> hmac = hmacHasher.finalize(); <span class="comment">// 进行加密</span></span><br><span class="line">    <span class="keyword">return</span> hmac;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="SHA">SHA<a class="header-anchor" href="#SHA"> ¶ </a></h3>
<h4 id="SHA1-2">SHA1<a class="header-anchor" href="#SHA1-2"> ¶ </a></h4>
<h5 id="简单调用-2">简单调用<a class="header-anchor" href="#简单调用-2"> ¶ </a></h5>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> hash = CryptoJS.SHA1(message);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> hash = CryptoJS.SHA1(wordArray);</span><br><span class="line"></span><br><span class="line"><span class="comment">// MAC</span></span><br><span class="line"><span class="keyword">var</span> hmac = CryptoJS.HmacSHA1(message, key);</span><br></pre></td></tr></table></figure>
<h4 id="SHA224">SHA224<a class="header-anchor" href="#SHA224"> ¶ </a></h4>
<h5 id="简单调用-3">简单调用<a class="header-anchor" href="#简单调用-3"> ¶ </a></h5>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> hash = CryptoJS.SHA224(message);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> hash = CryptoJS.SHA224(wordArray);</span><br><span class="line"></span><br><span class="line"><span class="comment">// MAC</span></span><br><span class="line"><span class="keyword">var</span> hmac = CryptoJS.HmacSHA224(message, key);</span><br></pre></td></tr></table></figure>
<h4 id="SHA256">SHA256<a class="header-anchor" href="#SHA256"> ¶ </a></h4>
<h5 id="简单调用-4">简单调用<a class="header-anchor" href="#简单调用-4"> ¶ </a></h5>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> hash = CryptoJS.SHA256(message);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> hash = CryptoJS.SHA256(wordArray);</span><br><span class="line"></span><br><span class="line"><span class="comment">// MAC</span></span><br><span class="line"><span class="keyword">var</span> hmac = CryptoJS.HmacSHA256(message, key);</span><br></pre></td></tr></table></figure>
<h4 id="复杂调用-2">复杂调用<a class="header-anchor" href="#复杂调用-2"> ¶ </a></h4>
<p>同md5，将<code>MD5</code>类替换为<code>SHA256</code>即可</p>
<h4 id="SHA3">SHA3<a class="header-anchor" href="#SHA3"> ¶ </a></h4>
<p>格式同上</p>
<h4 id="SHA384">SHA384<a class="header-anchor" href="#SHA384"> ¶ </a></h4>
<p>格式同上</p>
<h4 id="SHA512">SHA512<a class="header-anchor" href="#SHA512"> ¶ </a></h4>
<p>格式同上</p>
<h3 id="DES-2">DES<a class="header-anchor" href="#DES-2"> ¶ </a></h3>
<p>示例</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">desenExample</span>(<span class="params">data, key</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> data = CryptoJS.enc.Utf8.parse(data);</span><br><span class="line">    <span class="keyword">var</span> key = CryptoJS.enc.Utf8.parse(key);</span><br><span class="line">    <span class="keyword">var</span> cfg = &#123;</span><br><span class="line">        <span class="attr">mode</span>: CryptoJS.mode.ECB, <span class="comment">// 加密模式</span></span><br><span class="line">        <span class="attr">padding</span>: CryptoJS.pad.Pkcs7 <span class="comment">// 填充方式</span></span><br><span class="line">    &#125;;</span><br><span class="line">    <span class="keyword">var</span> result = CryptoJS.DES.encrypt(data, <span class="comment">// 待加密数据</span></span><br><span class="line">        key, <span class="comment">// 加密密钥</span></span><br><span class="line">        cfg);</span><br><span class="line">    <span class="keyword">var</span> restr = result.toString();</span><br><span class="line">    <span class="keyword">return</span> restr;</span><br><span class="line">&#125;</span><br><span class="line">desenExample(<span class="string">&quot;desExample&quot;</span>,<span class="string">&quot;12345678&quot;</span>);</span><br></pre></td></tr></table></figure>
<p>DESede/TripleDES<br>
将上述类名DES换为TripleDES即可</p>
<h3 id="AES-2">AES<a class="header-anchor" href="#AES-2"> ¶ </a></h3>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">aesExample</span>(<span class="params">data, key, iv</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> key = CryptoJS.enc.Utf8.parse(key);</span><br><span class="line">    <span class="keyword">var</span> iv = CryptoJS.enc.Utf8.parse(iv);</span><br><span class="line">    <span class="keyword">var</span> cfg = &#123;</span><br><span class="line">        <span class="attr">iv</span>: iv, <span class="comment">// iv</span></span><br><span class="line">        <span class="attr">mode</span>: CryptoJS.mode.CBC, <span class="comment">// 加密模式</span></span><br><span class="line">        <span class="attr">padding</span>: CryptoJS.pad.Pkcs7</span><br><span class="line">    &#125; <span class="comment">// 填充方式</span></span><br><span class="line">    <span class="comment">// format: CryptoJS.format.Hex // 以十六进制输出(默认采用Base64方式)</span></span><br><span class="line">    <span class="keyword">var</span> result = CryptoJS.AES.encrypt(data, <span class="comment">// 待加密数据</span></span><br><span class="line">        key, <span class="comment">// 加密密钥</span></span><br><span class="line">        cfg);</span><br><span class="line">    <span class="keyword">var</span> restr = result.toString();</span><br><span class="line">    <span class="keyword">return</span> restr;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="jsencrypt">jsencrypt<a class="header-anchor" href="#jsencrypt"> ¶ </a></h2>
<p><a target="_blank" rel="noopener" href="https://github.com/travist/jsencrypt">travist/jsencrypt: A Javascript library to perform OpenSSL RSA Encryption, Decryption, and Key Generation. (github.com)</a></p>
<h2 id="jsrsasign">jsrsasign<a class="header-anchor" href="#jsrsasign"> ¶ </a></h2>
<p><a target="_blank" rel="noopener" href="https://github.com/kjur/jsrsasign">kjur/jsrsasign: The ‘jsrsasign’ (RSA-Sign JavaScript Library) is an opensource free cryptography library supporting RSA/RSAPSS/ECDSA/DSA signing/validation, ASN.1, PKCS#1/5/8 private/public key, X.509 certificate, CRL, OCSP, CMS SignedData, TimeStamp, CAdES JSON Web Signature/Token in pure JavaScript. (github.com)</a></p>
<h2 id="RSA-js">RSA.js<a class="header-anchor" href="#RSA-js"> ¶ </a></h2>
<p><a target="_blank" rel="noopener" href="https://ohdave.com/rsa/">RSA In JavaScript - ohdave.com</a></p>
<hr class="footnotes-sep">
<section class="footnotes">
<ol class="footnotes-list">
<li id="fn1" class="footnote-item"><p>在电信和计算机网络领域，ASN.1（Abstract Syntax Notation One) 是一套标准，是描述数据的表示、编码、传输、解码的灵活的记法。它提供了一套正式、无歧义和精确的规则以描述独立于特定计算机硬件的对象结构。<strong>ASN.1是一种语言，一种标记语言，作用是描述数据结构。基于这种数据结构可以进行数据的表示、编码、传输和解码。</strong> <a href="#fnref1" class="footnote-backref">↩︎</a></p>
</li>
</ol>
</section>
</article><div class="post-copyright"><div class="post-copyright__author"><span class="post-copyright-meta">文章作者: </span><span class="post-copyright-info"><a href="mailto:undefined">Forgo7ten</a></span></div><div class="post-copyright__type"><span class="post-copyright-meta">文章链接: </span><span class="post-copyright-info"><a href="https://forgo7ten.github.io/AndroidReverse/2022/Learning_about_cryptographic_algorithms/">https://forgo7ten.github.io/AndroidReverse/2022/Learning_about_cryptographic_algorithms/</a></span></div><div class="post-copyright__notice"><span class="post-copyright-meta">版权声明: </span><span class="post-copyright-info">本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank">CC BY-NC-SA 4.0</a> 许可协议。转载请注明来自 <a href="https://Forgo7ten.github.io" target="_blank">Forgo7ten'blog</a>！</span></div></div><div class="tag_share"><div class="post-meta__tag-list"><a class="post-meta__tags" href="/tags/Android%E9%80%86%E5%90%91/">Android逆向</a></div><div class="post_share"><div class="social-share" data-image="http://forgo7ten.gitee.io/store/imgs/18.jpg" data-sites="facebook,twitter,wechat,weibo,qq"></div><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/social-share.js/dist/css/share.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/social-share.js/dist/js/social-share.min.js" defer></script></div></div><div class="post-reward"><div class="reward-button"><i class="fas fa-qrcode"></i> 打赏</div><div class="reward-main"><ul class="reward-all"><li class="reward-item"><a href="/images/wechat.png" target="_blank"><img class="post-qr-code-img" src="/images/wechat.png" alt="wechat"/></a><div class="post-qr-code-desc">wechat</div></li><li class="reward-item"><a href="/images/alipay.jpg" target="_blank"><img class="post-qr-code-img" src="/images/alipay.jpg" alt="alipay"/></a><div class="post-qr-code-desc">alipay</div></li></ul></div></div><nav class="pagination-post" id="pagination"><div class="prev-post pull-left"><a href="/AndroidReverse/2022/Android_dynamic_debugging_collection/"><img class="prev-cover" src="http://forgo7ten.gitee.io/store/imgs/3.jpg" onerror="onerror=null;src='/img/404.jpg'" alt="cover of previous post"><div class="pagination-info"><div class="label">上一篇</div><div class="prev_info">Android APK无源码动态调试合集</div></div></a></div><div class="next-post pull-right"><a href="/AndroidReverse/2022/Frida_all_in_one/"><img class="next-cover" src="http://forgo7ten.gitee.io/store/imgs/14.jpg" onerror="onerror=null;src='/img/404.jpg'" alt="cover of next post"><div class="pagination-info"><div class="label">下一篇</div><div class="next_info">Frida all in one</div></div></a></div></nav><div class="relatedPosts"><div class="headline"><i class="fas fa-thumbs-up fa-fw"></i><span>相关推荐</span></div><div class="relatedPosts-list"><div><a href="/AndroidReverse/2021/Analysis_of_WeChat/" title="vx逆向分析随笔"><img class="cover" src="http://forgo7ten.gitee.io/store/imgs/18.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2021-08-14</div><div class="title">vx逆向分析随笔</div></div></a></div><div><a href="/AndroidReverse/2022/Android_dynamic_debugging_collection/" title="Android APK无源码动态调试合集"><img class="cover" src="http://forgo7ten.gitee.io/store/imgs/3.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2022-01-21</div><div class="title">Android APK无源码动态调试合集</div></div></a></div><div><a href="/AndroidReverse/2021/Initial_xposed_module_development/" title="Xposed 模块开发一 环境搭建"><img class="cover" src="http://forgo7ten.gitee.io/store/imgs/11.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2021-07-12</div><div class="title">Xposed 模块开发一 环境搭建</div></div></a></div><div><a href="/AndroidReverse/2022/Frida_all_in_one/" title="Frida all in one"><img class="cover" src="http://forgo7ten.gitee.io/store/imgs/14.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2022-04-23</div><div class="title">Frida all in one</div></div></a></div><div><a href="/AndroidReverse/2022/Android_devices_init/" title="Android刷机记录"><img class="cover" src="http://forgo7ten.gitee.io/store/imgs/13.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2022-05-03</div><div class="title">Android刷机记录</div></div></a></div><div><a href="/AndroidReverse/2021/Android_traffic_capture_configuration_collection/" title="Android抓包配置合集"><img class="cover" src="http://forgo7ten.gitee.io/store/imgs/1.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2021-07-24</div><div class="title">Android抓包配置合集</div></div></a></div></div></div><hr/><div id="post-comment"><div class="comment-head"><div class="comment-headline"><i class="fas fa-comments fa-fw"></i><span> 评论</span></div></div><div class="comment-wrap"><div><div id="gitalk-container"></div></div></div></div></div><div class="aside-content" id="aside-content"><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><i class="fas fa-stream"></i><span>目录</span><span class="toc-percentage"></span></div><div class="toc-content"><ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#%E5%BA%8F%E5%88%97%E5%AF%86%E7%A0%81-%E6%B5%81%E5%AF%86%E7%A0%81"><span class="toc-number">1.</span> <span class="toc-text">序列密码(流密码)</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#RC4"><span class="toc-number">1.1.</span> <span class="toc-text">RC4</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%8E%9F%E7%90%86"><span class="toc-number">1.1.1.</span> <span class="toc-text">原理</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%88%9D%E5%A7%8B%E5%8C%96%E7%AE%97%E6%B3%95-KSA"><span class="toc-number">1.1.1.1.</span> <span class="toc-text">初始化算法(KSA)</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E4%BC%AA%E9%9A%8F%E6%9C%BA%E5%AD%90%E5%AF%86%E7%A0%81%E7%94%9F%E6%88%90%E7%AE%97%E6%B3%95-PRGA"><span class="toc-number">1.1.1.2.</span> <span class="toc-text">伪随机子密码生成算法(PRGA)</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%AE%9E%E7%8E%B0"><span class="toc-number">1.1.2.</span> <span class="toc-text">实现</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#C%E8%AF%AD%E8%A8%80"><span class="toc-number">1.1.2.1.</span> <span class="toc-text">C语言</span></a></li></ol></li></ol></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E5%88%86%E7%BB%84%E5%AF%86%E7%A0%81-%E5%9D%97%E5%8A%A0%E5%AF%86"><span class="toc-number">2.</span> <span class="toc-text">分组密码(块加密)</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%88%86%E7%BB%84%E5%AF%86%E7%A0%81%E6%A6%82%E5%BF%B5"><span class="toc-number">2.1.</span> <span class="toc-text">分组密码概念</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%88%86%E7%BB%84%E5%AF%86%E7%A0%81%E4%BA%94%E7%A7%8D%E5%B7%A5%E4%BD%9C%E6%A8%A1%E5%BC%8F"><span class="toc-number">2.1.1.</span> <span class="toc-text">分组密码五种工作模式</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E7%94%B5%E5%AD%90%E5%AF%86%E7%A0%81%E6%9C%AC%E6%A8%A1%E5%BC%8F-ECB"><span class="toc-number">2.1.1.1.</span> <span class="toc-text">电子密码本模式(ECB)</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%AF%86%E6%96%87%E9%93%BE%E6%8E%A5%E6%A8%A1%E5%BC%8F-CBC"><span class="toc-number">2.1.1.2.</span> <span class="toc-text">密文链接模式(CBC)</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%AF%86%E7%A0%81%E5%8F%8D%E9%A6%88%E6%A8%A1%E5%BC%8F-CFB"><span class="toc-number">2.1.1.3.</span> <span class="toc-text">密码反馈模式(CFB)</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E8%BE%93%E5%87%BA%E5%8F%8D%E9%A6%88%E6%A8%A1%E5%BC%8F-OFB"><span class="toc-number">2.1.1.4.</span> <span class="toc-text">输出反馈模式(OFB)</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E8%AE%A1%E6%95%B0%E5%99%A8%E6%A8%A1%E5%BC%8F-CTR"><span class="toc-number">2.1.1.5.</span> <span class="toc-text">计数器模式(CTR)</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%98%8E%E6%96%87%E5%AF%86%E7%A0%81%E5%9D%97%E9%93%BE%E6%8E%A5-PCBC"><span class="toc-number">2.1.1.6.</span> <span class="toc-text">明文密码块链接(PCBC)</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%88%86%E7%BB%84%E5%AF%86%E7%A0%81%E5%A1%AB%E5%85%85%E6%A8%A1%E5%BC%8F"><span class="toc-number">2.1.2.</span> <span class="toc-text">分组密码填充模式</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#NoPadding"><span class="toc-number">2.1.2.1.</span> <span class="toc-text">NoPadding</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#PKCS5Padding-PKCS7Padding"><span class="toc-number">2.1.2.2.</span> <span class="toc-text">PKCS5Padding &#x2F; PKCS7Padding</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#ANSI-X923Padding"><span class="toc-number">2.1.2.3.</span> <span class="toc-text">ANSI X923Padding</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#ISO10126Padding"><span class="toc-number">2.1.2.4.</span> <span class="toc-text">ISO10126Padding</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#ISO7816-4Padding"><span class="toc-number">2.1.2.5.</span> <span class="toc-text">ISO7816-4Padding</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#ZeroBytePadding"><span class="toc-number">2.1.2.6.</span> <span class="toc-text">ZeroBytePadding</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#TBCPadding%EF%BC%88Trailing-Bit-Compliment%EF%BC%89"><span class="toc-number">2.1.2.7.</span> <span class="toc-text">TBCPadding（Trailing-Bit-Compliment）</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#PKCS1Padding"><span class="toc-number">2.1.2.8.</span> <span class="toc-text">PKCS1Padding</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#DES"><span class="toc-number">2.2.</span> <span class="toc-text">DES</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%8E%9F%E7%90%86-2"><span class="toc-number">2.2.1.</span> <span class="toc-text">原理</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%AE%9E%E7%8E%B0-2"><span class="toc-number">2.2.2.</span> <span class="toc-text">实现</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#Java"><span class="toc-number">2.2.2.1.</span> <span class="toc-text">Java</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#DESede-3DES"><span class="toc-number">2.3.</span> <span class="toc-text">DESede(3DES)</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%AE%9E%E7%8E%B0-3"><span class="toc-number">2.3.1.</span> <span class="toc-text">实现</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Java-2"><span class="toc-number">2.3.2.</span> <span class="toc-text">Java</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#AES"><span class="toc-number">2.4.</span> <span class="toc-text">AES</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%8E%9F%E7%90%86-3"><span class="toc-number">2.4.1.</span> <span class="toc-text">原理</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%AD%97%E8%8A%82%E4%BB%A3%E6%8D%A2%E6%93%8D%E4%BD%9C"><span class="toc-number">2.4.1.1.</span> <span class="toc-text">字节代换操作</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E8%A1%8C%E4%BD%8D%E7%A7%BB%E6%93%8D%E4%BD%9C"><span class="toc-number">2.4.1.2.</span> <span class="toc-text">行位移操作</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%88%97%E6%B7%B7%E6%B7%86"><span class="toc-number">2.4.1.3.</span> <span class="toc-text">列混淆</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%AE%9E%E7%8E%B0-4"><span class="toc-number">2.4.2.</span> <span class="toc-text">实现</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#Java-3"><span class="toc-number">2.4.2.1.</span> <span class="toc-text">Java</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#TEA%E7%B3%BB%E5%88%97%E5%AF%86%E7%A0%81"><span class="toc-number">2.5.</span> <span class="toc-text">TEA系列密码</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#SM4%E7%AE%97%E6%B3%95"><span class="toc-number">2.6.</span> <span class="toc-text">SM4算法</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#SM4%E7%AE%97%E6%B3%95%E7%9A%84%E7%89%B9%E5%BE%81"><span class="toc-number">2.6.1.</span> <span class="toc-text">SM4算法的特征</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BD%BF%E7%94%A8python%E5%BA%93%E5%AF%B9SM4%E7%AE%97%E6%B3%95%E8%BF%9B%E8%A1%8C%E8%A7%A3%E5%AF%86"><span class="toc-number">2.6.2.</span> <span class="toc-text">使用python库对SM4算法进行解密</span></a></li></ol></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E9%9D%9E%E5%AF%B9%E7%A7%B0%E5%AF%86%E7%A0%81"><span class="toc-number">3.</span> <span class="toc-text">非对称密码</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#RSA"><span class="toc-number">3.1.</span> <span class="toc-text">RSA</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%9F%BA%E6%9C%AC%E5%8E%9F%E7%90%86"><span class="toc-number">3.1.1.</span> <span class="toc-text">基本原理</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%89%8D%E7%BD%AE%E6%95%B0%E5%AD%A6%E7%9F%A5%E8%AF%86"><span class="toc-number">3.1.1.1.</span> <span class="toc-text">前置数学知识</span></a><ol class="toc-child"><li class="toc-item toc-level-5"><a class="toc-link" href="#%E4%BA%92%E8%B4%A8%E5%85%B3%E7%B3%BB"><span class="toc-number">3.1.1.1.1.</span> <span class="toc-text">互质关系</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#%E6%AC%A7%E6%8B%89%E5%87%BD%E6%95%B0"><span class="toc-number">3.1.1.1.2.</span> <span class="toc-text">欧拉函数</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#%E6%AC%A7%E6%8B%89%E5%AE%9A%E7%90%86"><span class="toc-number">3.1.1.1.3.</span> <span class="toc-text">欧拉定理</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#%E6%A8%A1%E5%8F%8D%E5%85%83%E7%B4%A0"><span class="toc-number">3.1.1.1.4.</span> <span class="toc-text">模反元素</span></a></li></ol></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%85%AC%E9%92%A5%E4%B8%8E%E7%A7%81%E9%92%A5%E7%9A%84%E4%BA%A7%E7%94%9F"><span class="toc-number">3.1.1.2.</span> <span class="toc-text">公钥与私钥的产生</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%B6%88%E6%81%AF%E5%8A%A0%E5%AF%86"><span class="toc-number">3.1.1.3.</span> <span class="toc-text">消息加密</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%B6%88%E6%81%AF%E8%A7%A3%E5%AF%86"><span class="toc-number">3.1.1.4.</span> <span class="toc-text">消息解密</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%B8%BE%E4%BE%8B"><span class="toc-number">3.1.2.</span> <span class="toc-text">举例</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E7%A7%81%E9%92%A5%E5%85%AC%E9%92%A5%E7%9A%84%E4%BA%A7%E7%94%9F"><span class="toc-number">3.1.2.1.</span> <span class="toc-text">私钥公钥的产生</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E7%A0%B4%E8%A7%A3"><span class="toc-number">3.1.2.2.</span> <span class="toc-text">破解</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%AE%9E%E7%8E%B0-5"><span class="toc-number">3.1.3.</span> <span class="toc-text">实现</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#Java-4"><span class="toc-number">3.1.3.1.</span> <span class="toc-text">Java</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%B7%A5%E5%85%B7"><span class="toc-number">3.1.4.</span> <span class="toc-text">工具</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#RSAtool"><span class="toc-number">3.1.5.</span> <span class="toc-text">RSAtool</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#RSA-Converter"><span class="toc-number">3.1.5.1.</span> <span class="toc-text">RSA Converter</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#openssl"><span class="toc-number">3.1.5.2.</span> <span class="toc-text">openssl</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%88%86%E8%A7%A3%E6%95%B4%E6%95%B0%E5%B7%A5%E5%85%B7"><span class="toc-number">3.1.5.3.</span> <span class="toc-text">分解整数工具</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#python%E5%BA%93"><span class="toc-number">3.1.5.4.</span> <span class="toc-text">python库</span></a><ol class="toc-child"><li class="toc-item toc-level-5"><a class="toc-link" href="#primefac"><span class="toc-number">3.1.5.4.1.</span> <span class="toc-text">primefac</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#gmpy"><span class="toc-number">3.1.5.4.2.</span> <span class="toc-text">gmpy</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#gmpy2"><span class="toc-number">3.1.5.4.3.</span> <span class="toc-text">gmpy2</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#pycrypto"><span class="toc-number">3.1.5.4.4.</span> <span class="toc-text">pycrypto</span></a></li></ol></li></ol></li></ol></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E6%95%A3%E5%88%97%E7%AE%97%E6%B3%95-%E5%93%88%E5%B8%8C%E5%87%BD%E6%95%B0"><span class="toc-number">4.</span> <span class="toc-text">散列算法(哈希函数)</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#MD5"><span class="toc-number">4.1.</span> <span class="toc-text">MD5</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%89%B9%E5%BE%81"><span class="toc-number">4.1.1.</span> <span class="toc-text">特征</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%A0%B4%E8%A7%A3-2"><span class="toc-number">4.1.2.</span> <span class="toc-text">破解</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#SHA1"><span class="toc-number">4.2.</span> <span class="toc-text">SHA1</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E8%AF%81%E4%B9%A6%E6%A0%BC%E5%BC%8F%E8%A7%A3%E6%9E%90"><span class="toc-number">5.</span> <span class="toc-text">证书格式解析</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#PEM%E6%A0%BC%E5%BC%8F%E8%AF%81%E4%B9%A6"><span class="toc-number">5.1.</span> <span class="toc-text">PEM格式证书</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%AF%B9RSA%E7%9A%84pem%E8%AF%81%E4%B9%A6%E6%A0%BC%E5%BC%8F%E8%A7%A3%E6%9E%90"><span class="toc-number">5.1.1.</span> <span class="toc-text">对RSA的pem证书格式解析</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#PKCS-1%E6%A0%BC%E5%BC%8Fpem%E8%A7%A3%E6%9E%90"><span class="toc-number">5.1.1.1.</span> <span class="toc-text">PKCS#1格式pem解析</span></a><ol class="toc-child"><li class="toc-item toc-level-5"><a class="toc-link" href="#%E7%A7%81%E9%92%A5"><span class="toc-number">5.1.1.1.1.</span> <span class="toc-text">私钥</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#%E5%85%AC%E9%92%A5"><span class="toc-number">5.1.1.1.2.</span> <span class="toc-text">公钥</span></a></li></ol></li><li class="toc-item toc-level-4"><a class="toc-link" href="#PKCS-8%E6%A0%BC%E5%BC%8Fpem%E8%A7%A3%E6%9E%90"><span class="toc-number">5.1.1.2.</span> <span class="toc-text">PKCS#8格式pem解析</span></a><ol class="toc-child"><li class="toc-item toc-level-5"><a class="toc-link" href="#%E7%A7%81%E9%92%A5-2"><span class="toc-number">5.1.1.2.1.</span> <span class="toc-text">私钥</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#%E5%85%AC%E9%92%A5-2"><span class="toc-number">5.1.1.2.2.</span> <span class="toc-text">公钥</span></a></li></ol></li><li class="toc-item toc-level-4"><a class="toc-link" href="#openssl-%E7%9B%B8%E5%85%B3%E5%91%BD%E4%BB%A4"><span class="toc-number">5.1.1.3.</span> <span class="toc-text">openssl 相关命令</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%85%B6%E4%BB%96"><span class="toc-number">5.1.2.</span> <span class="toc-text">其他</span></a></li></ol></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#JAVA%E5%AE%9E%E7%8E%B0%E5%8A%A0%E8%A7%A3%E5%AF%86"><span class="toc-number">6.</span> <span class="toc-text">JAVA实现加解密</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#Java%E5%8A%A0%E8%A7%A3%E5%AF%86%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE"><span class="toc-number">6.1.</span> <span class="toc-text">Java加解密环境配置</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#1-%E8%A7%A3%E9%99%A4java-jdk%E6%94%BF%E7%AD%96%E9%99%90%E5%88%B6"><span class="toc-number">6.1.1.</span> <span class="toc-text">1. 解除java jdk政策限制</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%A3%80%E6%B5%8B%E6%98%AF%E5%90%A6%E5%B7%B2%E7%BB%8F%E8%A7%A3%E9%99%A4%E9%99%90%E5%88%B6"><span class="toc-number">6.1.1.1.</span> <span class="toc-text">检测是否已经解除限制</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2-%E9%85%8D%E7%BD%AEBouncyCastle"><span class="toc-number">6.1.2.</span> <span class="toc-text">2.配置BouncyCastle</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%EF%BC%88%E6%96%B9%E6%B3%95%E4%B8%80%EF%BC%89%E5%85%A8%E5%B1%80%E9%9D%99%E6%80%81%E9%85%8D%E7%BD%AE"><span class="toc-number">6.1.2.1.</span> <span class="toc-text">（方法一）全局静态配置</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%EF%BC%88%E6%96%B9%E6%B3%95%E4%BA%8C%EF%BC%89%E5%8A%A8%E6%80%81%E6%B7%BB%E5%8A%A0jar"><span class="toc-number">6.1.2.2.</span> <span class="toc-text">（方法二）动态添加jar</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E9%AA%8C%E8%AF%81%E4%BD%BF%E7%94%A8"><span class="toc-number">6.1.2.3.</span> <span class="toc-text">验证使用</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%85%8D%E7%BD%AECommonsCodec"><span class="toc-number">6.1.3.</span> <span class="toc-text">配置CommonsCodec</span></a></li></ol></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#JavaScript%E5%AE%9E%E7%8E%B0%E5%8A%A0%E8%A7%A3%E5%AF%86"><span class="toc-number">7.</span> <span class="toc-text">JavaScript实现加解密</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#CryptoJS%E5%BA%93%E4%BD%BF%E7%94%A8"><span class="toc-number">7.1.</span> <span class="toc-text">CryptoJS库使用</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%A7%A3%E6%9E%90%E6%95%B0%E6%8D%AE"><span class="toc-number">7.1.1.</span> <span class="toc-text">解析数据</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#MD"><span class="toc-number">7.1.2.</span> <span class="toc-text">MD</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#MD5-2"><span class="toc-number">7.1.2.1.</span> <span class="toc-text">MD5</span></a><ol class="toc-child"><li class="toc-item toc-level-5"><a class="toc-link" href="#%E7%AE%80%E5%8D%95%E8%B0%83%E7%94%A8"><span class="toc-number">7.1.2.1.1.</span> <span class="toc-text">简单调用</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#%E5%A4%8D%E6%9D%82%E8%B0%83%E7%94%A8"><span class="toc-number">7.1.2.1.2.</span> <span class="toc-text">复杂调用</span></a></li></ol></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#SHA"><span class="toc-number">7.1.3.</span> <span class="toc-text">SHA</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#SHA1-2"><span class="toc-number">7.1.3.1.</span> <span class="toc-text">SHA1</span></a><ol class="toc-child"><li class="toc-item toc-level-5"><a class="toc-link" href="#%E7%AE%80%E5%8D%95%E8%B0%83%E7%94%A8-2"><span class="toc-number">7.1.3.1.1.</span> <span class="toc-text">简单调用</span></a></li></ol></li><li class="toc-item toc-level-4"><a class="toc-link" href="#SHA224"><span class="toc-number">7.1.3.2.</span> <span class="toc-text">SHA224</span></a><ol class="toc-child"><li class="toc-item toc-level-5"><a class="toc-link" href="#%E7%AE%80%E5%8D%95%E8%B0%83%E7%94%A8-3"><span class="toc-number">7.1.3.2.1.</span> <span class="toc-text">简单调用</span></a></li></ol></li><li class="toc-item toc-level-4"><a class="toc-link" href="#SHA256"><span class="toc-number">7.1.3.3.</span> <span class="toc-text">SHA256</span></a><ol class="toc-child"><li class="toc-item toc-level-5"><a class="toc-link" href="#%E7%AE%80%E5%8D%95%E8%B0%83%E7%94%A8-4"><span class="toc-number">7.1.3.3.1.</span> <span class="toc-text">简单调用</span></a></li></ol></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%A4%8D%E6%9D%82%E8%B0%83%E7%94%A8-2"><span class="toc-number">7.1.3.4.</span> <span class="toc-text">复杂调用</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#SHA3"><span class="toc-number">7.1.3.5.</span> <span class="toc-text">SHA3</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#SHA384"><span class="toc-number">7.1.3.6.</span> <span class="toc-text">SHA384</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#SHA512"><span class="toc-number">7.1.3.7.</span> <span class="toc-text">SHA512</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#DES-2"><span class="toc-number">7.1.4.</span> <span class="toc-text">DES</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#AES-2"><span class="toc-number">7.1.5.</span> <span class="toc-text">AES</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#jsencrypt"><span class="toc-number">7.2.</span> <span class="toc-text">jsencrypt</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#jsrsasign"><span class="toc-number">7.3.</span> <span class="toc-text">jsrsasign</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#RSA-js"><span class="toc-number">7.4.</span> <span class="toc-text">RSA.js</span></a></li></ol></li></ol></div></div></div></div></main><footer id="footer" style="background-image: url('http://forgo7ten.gitee.io/store/imgs/18.jpg')"><div id="footer-wrap"><div class="copyright">&copy;2020 - 2023 By Forgo7ten</div><div class="framework-info"><span>框架 </span><a target="_blank" rel="noopener" href="https://hexo.io">Hexo</a><span class="footer-separator">|</span><span>主题 </span><a target="_blank" rel="noopener" href="https://github.com/jerryc127/hexo-theme-butterfly">Butterfly</a></div><div class="footer_custom_text">Hi, welcome to my <a href="https://Forgo7ten.github.io/">blog</a>!</div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="阅读模式"><i class="fas fa-book-open"></i></button><button id="translateLink" type="button" title="简繁转换">繁</button><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fas fa-adjust"></i></button><button id="hide-aside-btn" type="button" title="单栏和双栏切换"><i class="fas fa-arrows-alt-h"></i></button></div><div id="rightside-config-show"><button id="rightside_config" type="button" title="设置"><i class="fas fa-cog fa-spin"></i></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fas fa-list-ul"></i></button><a id="to_comment" href="#post-comment" title="直达评论"><i class="fas fa-comments"></i></a><button id="go-up" type="button" title="回到顶部"><i class="fas fa-arrow-up"></i></button></div></div><div id="local-search"><div class="search-dialog"><nav class="search-nav"><span class="search-dialog-title">本地搜索</span><span id="loading-status"></span><button class="search-close-button"><i class="fas fa-times"></i></button></nav><div class="is-center" id="loading-database"><i class="fas fa-spinner fa-pulse"></i><span>  数据库加载中</span></div><div class="search-wrap"><div id="local-search-input"><div class="local-search-box"><input class="local-search-box--input" placeholder="搜索文章" type="text"/></div></div><hr/><div id="local-search-results"></div></div></div><div id="search-mask"></div></div><div><script src="/js/utils.js"></script><script src="/js/main.js"></script><script src="/js/tw_cn.js"></script><script src="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox.umd.js"></script><script src="https://cdn.jsdelivr.net/npm/instant.page/instantpage.min.js" type="module"></script><script src="https://cdn.jsdelivr.net/npm/vanilla-lazyload/dist/lazyload.iife.min.js"></script><script src="https://cdn.jsdelivr.net/npm/node-snackbar/dist/snackbar.min.js"></script><script src="/js/search/local-search.js"></script><script>var preloader = {
  endLoading: () => {
    document.body.style.overflow = 'auto';
    document.getElementById('loading-box').classList.add("loaded")
  },
  initLoading: () => {
    document.body.style.overflow = '';
    document.getElementById('loading-box').classList.remove("loaded")

  }
}
window.addEventListener('load',preloader.endLoading())</script><div class="js-pjax"><link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/katex@latest/dist/katex.min.css"><script src="https://cdn.jsdelivr.net/npm/katex@latest/dist/contrib/copy-tex.min.js"></script><link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/katex@latest/dist/contrib/copy-tex.css"><script>(() => {
  document.querySelectorAll('#article-container span.katex-display').forEach(item => {
    btf.wrap(item, 'div', { class: 'katex-wrap'})
  })
})()</script><script>function addGitalkSource () {
  const ele = document.createElement('link')
  ele.rel = 'stylesheet'
  ele.href= 'https://cdn.jsdelivr.net/npm/gitalk/dist/gitalk.min.css'
  document.getElementsByTagName('head')[0].appendChild(ele)
}

function loadGitalk () {
  function initGitalk () {
    var gitalk = new Gitalk(Object.assign({
      clientID: '9e01c692fcf5a9e47867',
      clientSecret: '6d5297eda0643a171a9e5510f5ea1c29ad851389',
      repo: 'Forgo7ten.github.io',
      owner: 'Forgo7ten',
      admin: ['Forgo7ten'],
      id: 'bb43b937c41baacde58ef040c9b2ceb2',
      updateCountCallback: commentCount
    },{"language":"en","perPage":20,"distractionFreeMode":true,"pagerDirection":"last","createIssueManually":true}))

    gitalk.render('gitalk-container')
  }

  if (typeof Gitalk === 'function') initGitalk()
  else {
    addGitalkSource()
    getScript('https://cdn.jsdelivr.net/npm/gitalk@latest/dist/gitalk.min.js').then(initGitalk)
  }
}

function commentCount(n){
  let isCommentCount = document.querySelector('#post-meta .gitalk-comment-count')
  if (isCommentCount) {
    isCommentCount.innerHTML= n
  }
}

if ('Gitalk' === 'Gitalk' || !false) {
  if (false) btf.loadComment(document.getElementById('gitalk-container'), loadGitalk)
  else loadGitalk()
} else {
  function loadOtherComment () {
    loadGitalk()
  }
}</script></div><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/dist/activate-power-mode.min.js"></script><script>POWERMODE.colorful = true;
POWERMODE.shake = true;
POWERMODE.mobile = false;
document.body.addEventListener('input', POWERMODE);
</script><script id="click-show-text" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/dist/click-show-text.min.js" data-mobile="false" data-text="ヾ(≧▽≦*)o 点个收藏叭,(*^▽^*),w(ﾟДﾟ)w,ㄟ(≧◇≦)ㄏ,(/≧▽≦)/点个关注叭,Σ(っ °Д °;)っ,(●ˇ∀ˇ●),( •̀ ω •́ )✧,(*/ω＼*),ヽ(*。&gt;Д&lt;)o゜真的不收藏一下嘛,(～o￣3￣)～,ヽ（≧□≦）ノ" data-fontsize="15px" data-random="false" async="async"></script><script src="https://cdn.jsdelivr.net/npm/pjax/pjax.min.js"></script><script>let pjaxSelectors = ["title","#config-diff","#body-wrap","#rightside-config-hide","#rightside-config-show",".js-pjax"]

var pjax = new Pjax({
  elements: 'a:not([target="_blank"])',
  selectors: pjaxSelectors,
  cacheBust: false,
  analytics: false,
  scrollRestoration: false
})

document.addEventListener('pjax:send', function () {

  // removeEventListener scroll 
  window.tocScrollFn && window.removeEventListener('scroll', window.tocScrollFn)
  window.scrollCollect && window.removeEventListener('scroll', scrollCollect)

  typeof preloader === 'object' && preloader.initLoading()
  document.getElementById('rightside').style.cssText = "opacity: ''; transform: ''"
  
  if (window.aplayers) {
    for (let i = 0; i < window.aplayers.length; i++) {
      if (!window.aplayers[i].options.fixed) {
        window.aplayers[i].destroy()
      }
    }
  }

  typeof typed === 'object' && typed.destroy()

  //reset readmode
  const $bodyClassList = document.body.classList
  $bodyClassList.contains('read-mode') && $bodyClassList.remove('read-mode')

})

document.addEventListener('pjax:complete', function () {
  window.refreshFn()

  document.querySelectorAll('script[data-pjax]').forEach(item => {
    const newScript = document.createElement('script')
    const content = item.text || item.textContent || item.innerHTML || ""
    Array.from(item.attributes).forEach(attr => newScript.setAttribute(attr.name, attr.value))
    newScript.appendChild(document.createTextNode(content))
    item.parentNode.replaceChild(newScript, item)
  })

  GLOBAL_CONFIG.islazyload && window.lazyLoadInstance.update()

  typeof chatBtnFn === 'function' && chatBtnFn()
  typeof panguInit === 'function' && panguInit()

  // google analytics
  typeof gtag === 'function' && gtag('config', '', {'page_path': window.location.pathname});

  // baidu analytics
  typeof _hmt === 'object' && _hmt.push(['_trackPageview',window.location.pathname]);

  typeof loadMeting === 'function' && document.getElementsByClassName('aplayer').length && loadMeting()

  // prismjs
  typeof Prism === 'object' && Prism.highlightAll()

  typeof preloader === 'object' && preloader.endLoading()
})

document.addEventListener('pjax:error', (e) => {
  if (e.request.status === 404) {
    pjax.loadUrl('/404.html')
  }
})</script><script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script></div><script src="/live2dw/lib/L2Dwidget.min.js?094cbace49a39548bed64abff5988b05"></script><script>L2Dwidget.init({"pluginRootPath":"live2dw/","pluginJsPath":"lib/","pluginModelPath":"assets/","tagMode":false,"debug":false,"model":{"scale":1,"hHeadPos":0.5,"vHeadPos":0.618,"jsonPath":"/live2dw/assets/z16.model.json"},"display":{"superSample":2,"width":200,"height":400,"position":"right","hOffset":0,"vOffset":-20},"mobile":{"show":true,"scale":0.5},"react":{"opacityDefault":0.7,"opacityOnHover":0.2},"log":false});</script></body></html>